27 #include <Classes.hpp>
28 #include <Controls.hpp>
29 #include <StdCtrls.hpp>
31 #include <Buttons.hpp>
32 #include <ExtCtrls.hpp>
34 #include <Dialogs.hpp>
35 #include <Graphics.hpp>
36 #include <ComCtrls.hpp>
59 #include <Filectrl.hpp>
62 #include <Vcl.HTMLHelpViewer.hpp>
63 #pragma package(smart_init)
64 #pragma link "Vcl.HTMLHelpViewer" //added at v2.0.0 for access to the .chm help file
65 #pragma resource "*.dfm"
84 Screen->Cursor = TCursor(-11);
150 "program operation may be restricted");
160 Application->HelpFile = AnsiString(
CurDir +
"\\Help.chm");
168 int DispW = (Screen->Width - 64) / 16;
169 int DispH = (Screen->Height - 192) / 16;
173 Display =
new TDisplay(
MainScreen,
PerformanceLogBox,
OutputLog1,
OutputLog2,
OutputLog3,
OutputLog4,
OutputLog5,
OutputLog6,
OutputLog7,
OutputLog8,
310 SpeedButton96->Glyph->LoadFromResourceName(0,
"ConcourseGlyph");
374 FontButton->Glyph->LoadFromResourceName(0,
"FontGraphic");
375 HomeButton->Glyph->LoadFromResourceName(0,
"Home");
394 SetGapsButton->Glyph->LoadFromResourceName(0,
"ConnectGaps");
405 CallOnImage->Picture->Bitmap->LoadFromResourceName(0,
"CallingOn");
406 CrashImage->Picture->Bitmap->LoadFromResourceName(0,
"CrashWarning");
407 DerailImage->Picture->Bitmap->LoadFromResourceName(0,
"DerailWarning");
408 SignalStopImage->Picture->Bitmap->LoadFromResourceName(0,
"SignalStopWarning");
409 SPADImage->Picture->Bitmap->LoadFromResourceName(0,
"SPADWarning");
410 TrainFailedImage->Picture->Bitmap->LoadFromResourceName(0,
"TrainFailedWarning");
412 DistanceKey->Picture->Bitmap->LoadFromResourceName(0,
"DistanceKey");
413 PrefDirKey->Picture->Bitmap->LoadFromResourceName(0,
"PrefDirKey");
415 TrackLinkedImage->Picture->Bitmap->LoadFromResourceName(0,
"TrackLinkedGraphic");
417 GapsNotSetImage->Picture->Bitmap->LoadFromResourceName(0,
"GapsNotSetGraphic");
418 GapsSetImage->Picture->Bitmap->LoadFromResourceName(0,
"GapsSetGraphic");
442 AnsiString NL =
'\n';
443 const AnsiString TTLabelStr1 =
"Start new train" + NL +
"Start new service from a split" + NL +
"Start new service from another service" + NL +
444 "Start new non-repeating shuttle finish service" + NL +
"Start new shuttle train at a timetabled stop" + NL +
445 "Start new shuttle service from a feeder";
447 const AnsiString TTLabelStr2 =
"Pass" + NL +
"Be joined by another train" + NL +
"Front split" + NL +
"Rear split" + NL +
"Change direction of train";
449 const AnsiString TTLabelStr3 =
"Finish && form a new service" + NL +
"Finish && join another train" + NL +
"Finish && exit railway" + NL +
450 "Finish && repeat shuttle, finally remain here" + NL +
"Finish && repeat shuttle, finally form a finishing service" + NL +
451 "Finish non-repeating shuttle feeder service" + NL +
"Finish && remain here";
453 const AnsiString TTLabelStr4 =
"HH:MM" + NL +
"HH:MM" + NL +
"HH:MM" + NL +
"HH:MM" + NL +
"HH:MM" + NL +
"HH:MM" + NL +
"HH:MM" + NL +
"HH:MM" + NL +
454 "HH:MM" + NL +
"HH:MM" + NL +
"HH:MM" + NL +
"HH:MM" + NL +
"HH:MM" + NL +
"HH:MM" + NL +
"HH:MM" + NL +
"HH:MM" + NL +
"HH:MM" + NL +
" " + NL +
"R";
456 const AnsiString TTLabelStr5 =
"HH:MM ';' Location" + NL +
"HH:MM ';' HH:MM ';' Location";
458 const AnsiString TTLabelStr6 =
"+ rear element ID - space - front element ID [+ optional ';S']" + NL +
"+ ref. of the train that splits" + NL +
459 "+ other service ref." + NL +
"+ shuttle service ref." + NL +
"+ rear element ID - space - front element ID ';' linked shuttle ref." + NL +
460 "+ linked shuttle service ref. ';' feeder service ref." + NL +
"+ location" + NL +
"+ joining train ref." + NL +
"+ new service ref." + NL +
461 "+ new service ref." + NL +
" " + NL +
"+ new service ref." + NL +
"+ ref. of train to join" + NL +
462 "+ list of valid exit element IDs (at least 1) separated by spaces" + NL +
"+ linked shuttle service ref.";
464 const AnsiString TTLabelStr7 =
"Arrival OR departure time (program will determine which from the context) + location." + NL +
465 "Arrival time, departure time (with no events between) + location";
467 const AnsiString TTLabelStr9 =
"Timetable entries" + NL +
"(service references etc.)";
468 const AnsiString TTLabelStr11 =
"Timetable" + NL +
"start time";
470 const AnsiString TTLabelStr12 =
"NB: WITHIN SERVICES commas must" + NL +
"not be used (have special meanings)," + NL +
471 "and semicolons may only be used to" + NL +
"separate service components.";
473 const AnsiString TTLabelStr13 =
"+ linked shuttle service ref. ';' finishing service ref." + NL +
"+ linked shuttle service ref.";
475 const AnsiString TTLabelStr15 =
"Repeat the service + ';' minutes between repeats ';' digit increment ';' number of repeats (last line of service)";
492 AnsiString ColourStr =
"";
493 std::ifstream ColFile((
CurDir +
"\\Background.col").c_str());
504 else if((ColourStr !=
"white") && (ColourStr !=
"black") && (ColourStr !=
"blue"))
510 if(ColourStr ==
"white")
514 else if(ColourStr ==
"blue")
527 AnsiString RHSigStr =
"";
528 std::ifstream SignalFile((
CurDir +
"\\Signal.hnd").c_str());
529 if(SignalFile.fail())
531 SigImagePanel->Caption =
"Signals will be on the left hand side of the track";
537 std::ofstream SignalFile((
CurDir +
"\\Signal.hnd").c_str());
538 if(!SignalFile.fail())
548 if(RHSigStr ==
"RHSignals")
560 SigImagePanel->Caption =
"Signals will be on the right hand side of the track";
570 SigImagePanel->Caption =
"Signals will be on the left hand side of the track";
576 std::ofstream SignalFile((
CurDir +
"\\Signal.hnd").c_str());
577 if(!SignalFile.fail())
595 std::ifstream SplashFile((
CurDir +
"\\GNU").c_str());
596 if(SplashFile.fail())
599 "This program is free software released under the terms of the GNU General Public License Version 3, as published by the Free Software Foundation. It may be used or redistributed in accordance with that license and is released in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details - you should have received a copy along with this program but if not see <http://www.gnu.org/licenses/>.");
600 std::ofstream SplashFile((
CurDir +
"\\GNU").c_str());
601 if(!SplashFile.fail())
605 if((Screen->Width < 1024) || (Screen->Height < 768))
607 ShowMessage(
"Please note that this program works best with a screen resolution of at least 1024 x 768. Please change if possible");
613 WindowState = wsMaximized;
625 Screen->Cursor = TCursor(-2);
652 char *LocalNumericInformation = setlocale(LC_NUMERIC,
"");
654 if(LocalNumericInformation ==
"")
659 struct lconv *conv = &Locale;
665 catch(
const EFOpenError &e)
669 MessageDlg(e.Message +
" - program must terminate", mtError, But, 0);
670 Application->Terminate();
673 catch(
const Exception &e)
677 AnsiString Message =
"A fatal error occurred during the program setup process, the program must terminate. Message = " + e.Message;
678 MessageDlg(Message, mtError, But, 0);
680 Application->Terminate();
710 catch(
const Exception &e)
726 catch(
const Exception &e)
745 Screen->Cursor = TCursor(-2);
755 Screen->Cursor = TCursor(-2);
762 catch(
const Exception &e)
779 catch(
const Exception &e)
792 UnicodeString strVersion = L
"N/A";
794 VersionSize = GetFileVersionInfoSizeW(Application->ExeName.c_str(), &VersionHandle);
797 pBuffer =
new BYTE[VersionSize];
799 if(GetFileVersionInfoW(Application->ExeName.c_str(), VersionHandle, VersionSize, pBuffer))
801 VS_FIXEDFILEINFO *fi;
805 if(VerQueryValueW(pBuffer, L
"\\", (
void**)&fi, &buflen))
808 strVersion.sprintf(L
"%d.%d.%d", HIWORD(fi->dwFileVersionMS), LOWORD(fi->dwFileVersionMS), HIWORD(fi->dwFileVersionLS)
817 return L
" v" + strVersion;
833 catch(
const Exception &e)
852 catch(
const Exception &e)
865 if(((TSpeedButton*)Sender)->Down)
877 catch(
const Exception &e)
911 ShowMessage(
"Incomplete track or other error - see inverted element (may be behind this message)");
922 ShowMessage(
"Unable to set any track links");
935 ShowMessage(
"Successful Completion");
951 catch(
const Exception &e)
972 catch(
const Exception &e)
991 catch(
const Exception &e)
1010 catch(
const Exception &e)
1029 TFont *TempFont =
new TFont;
1037 TempText.
Font = DisplayFont;
1044 else if(Key ==
'\x1B')
1050 catch(
const Exception &e)
1069 catch(
const Exception &e)
1084 ShowMessage(
"Error, location name being entered without an entry in LNPendingList");
1104 Screen->Cursor = TCursor(-11);
1106 AnsiString ExistingName;
1113 UnicodeString MessageStr = UnicodeString(
"Another location named '") +
LocationNameTextBox->Text +
1114 UnicodeString(
"' already exists. If you continue its name will be erased. Do you wish to continue?");
1115 int button = Application->MessageBox(MessageStr.c_str(), L
"Warning!", MB_YESNO | MB_ICONWARNING);
1119 Screen->Cursor = TCursor(-2);
1130 bool UseExistingPosition =
false;
1137 if(ExistingName !=
"")
1140 UseExistingPosition =
true;
1143 Screen->Cursor = TCursor(-2);
1157 bool UseExistingPosition =
false;
1159 UseExistingPosition =
true;
1162 Screen->Cursor = TCursor(-2);
1174 LocStr = LocStr.Trim();
1183 if((LocStr !=
"") && (LocStr[1] >=
'0') && (LocStr[1] <=
'9'))
1185 Screen->Cursor = TCursor(-2);
1186 ShowMessage(
"Location name can't begin with a number");
1194 if(LocStr.Length() > 50)
1196 Screen->Cursor = TCursor(-2);
1197 ShowMessage(
"Location name too long, 50 characters maximum");
1205 for(
int x = 1; x <= LocStr.Length(); x++)
1207 char Ch = LocStr[x];
1208 if((Ch !=
' ') && (Ch !=
'&') && (Ch !=
'(') && (Ch !=
')') && (Ch !=
':') && (Ch != 39) && (Ch !=
'.') && (Ch !=
'-') && (Ch !=
'+') &&
1209 (Ch !=
'/') && ((Ch <
'0') || (Ch >
'9')) && ((Ch <
'A') || (Ch >
'Z')) && ((Ch <
'a') || (Ch >
'z')))
1211 Screen->Cursor = TCursor(-2);
1213 "Location name contains one or more invalid characters, must be alphanumeric, brackets, space, full stop, colon, inverted comma, '-', '+', '/' or '&&'");
1224 Screen->Cursor = TCursor(-2);
1225 ShowMessage(
"Location name cannot be 'cdt', this name would interfere with the timetable");
1236 bool UseExistingPosition =
false;
1237 if(ExistingName !=
"")
1240 UseExistingPosition =
true;
1243 Screen->Cursor = TCursor(-2);
1252 Screen->Cursor = TCursor(-2);
1255 catch(
const Exception &e)
1276 catch(
const Exception &e)
1289 int Dist = 0, SpeedLimit = 0;
1292 DistanceStr =
"No change";
1295 SpeedStr =
"No change";
1298 if(DistanceStr ==
"No change")
1300 if(SpeedStr ==
"No change")
1310 if(((Dist != -1) && (DistanceStr.Length() > 6)) || ((SpeedLimit != -1) && (SpeedStr.Length() > 6)))
1312 ShowMessage(
"One or more entries too long");
1316 if((DistanceStr ==
"") || (SpeedStr ==
""))
1318 ShowMessage(
"One or more entries blank");
1324 for(
int x = 1; x <= DistanceStr.Length(); x++)
1326 if((DistanceStr[x] <
'0') || (DistanceStr[x] >
'9'))
1328 ShowMessage(
"Track length value must be a positive whole number, or blank for no change");
1336 for(
int x = 1; x <= DistanceStr.Length(); x++)
1338 if((DistanceStr[x] <
'0') || (DistanceStr[x] >
'9'))
1340 ShowMessage(
"Distance must be a positive whole number");
1348 for(
int x = 1; x <= SpeedStr.Length(); x++)
1350 if((SpeedStr[x] <
'0') || (SpeedStr[x] >
'9'))
1352 ShowMessage(
"Speed limit must be a positive whole number, or blank for no change");
1360 for(
int x = 1; x <= SpeedStr.Length(); x++)
1362 if((SpeedStr[x] <
'0') || (SpeedStr[x] >
'9'))
1364 ShowMessage(
"Speed limit must be a positive whole number, or 'Mixed'");
1371 Dist = DistanceStr.ToInt();
1372 if(SpeedLimit != -1)
1373 SpeedLimit = SpeedStr.ToInt();
1381 if(((Dist != -1) && (Dist < 20)) || ((SpeedLimit != -1) && (SpeedLimit < 10)) || ((SpeedLimit != -1) && (SpeedLimit >
TTrain::MaximumSpeedLimit)))
1384 ShowMessage(
"Lengths must be 20m or more, and speeds must be between 10km/h and 400km/h");
1397 bool NamedLocPresent =
false;
1400 for(
int x = LowSelectHLoc; x < HighSelectHLoc; x++)
1402 for(
int y = LowSelectVLoc; y < HighSelectVLoc; y++)
1405 NamedLocPresent =
true;
1409 if(NamedLocPresent && (Dist < 50))
1411 ShowMessage(
"Note: Named location elements are quite short. If they are too short the simulation might depart too far from reality.");
1414 if(NamedLocPresent && (Dist > 200))
1416 ShowMessage(
"Note: Named location elements are quite long. If they are too long the simulation might depart too far from reality.");
1419 for(
int x = LowSelectHLoc; x < HighSelectHLoc; x++)
1421 for(
int y = LowSelectVLoc; y < HighSelectVLoc; y++)
1458 catch(
const Exception &e)
1481 catch(
const Exception &e)
1493 TMsgDlgButtons Buttons;
1494 Buttons << mbYes << mbNo;
1495 if(MessageDlg(
"This will reset the selected elements to default lengths & speed limits. Proceed?", mtWarning, Buttons, 0) == mrNo)
1513 for(
int x = LowSelectHLoc; x < HighSelectHLoc; x++)
1515 for(
int y = LowSelectVLoc; y < HighSelectVLoc; y++)
1569 throw Exception(
"Error, XLinkPos > 1 in SetOneDefaultTrackLength at " + AnsiString(TrackElement.
HLoc) +
" & " +
1570 AnsiString(TrackElement.
VLoc));
1586 catch(
const Exception &e)
1598 TMsgDlgButtons Buttons;
1599 Buttons << mbYes << mbNo;
1600 if(MessageDlg(
"This will reset ALL track elements to default lengths & speed limits. Proceed?", mtWarning, Buttons, 0) == mrNo)
1621 catch(
const Exception &e)
1649 bool GraphicFoundInVector =
false;
1650 for(TTrack::TUserGraphicVector::iterator UGVIt =
Track->
UserGraphicVector.begin(); UGVIt < Track->UserGraphicVector.end(); UGVIt++)
1652 if(UGMIt->first == UGVIt->FileName)
1654 GraphicFoundInVector =
true;
1658 if(!GraphicFoundInVector)
1660 delete UGMIt->second;
1676 catch(
const Exception &e)
1716 catch(
const Exception &e)
1755 catch(
const Exception &e)
1779 catch(
const Exception &e)
1805 catch(
const Exception &e)
1824 catch(
const Exception &e)
1839 ShowMessage(
"No preferred direction selection");
1843 Screen->Cursor = TCursor(-11);
1848 Screen->Cursor = TCursor(-2);
1851 catch(
const Exception &e)
1864 TMsgDlgButtons Buttons;
1865 Buttons << mbYes << mbNo;
1866 if(MessageDlg(
"Do you really want to clear all preferred directions?", mtWarning, Buttons, 0) == mrNo)
1882 catch(
const Exception &e)
1897 Screen->Cursor = TCursor(-11);
1906 Screen->Cursor = TCursor(-2);
1909 catch(
const Exception &e)
1927 catch(
const Exception &e)
1948 catch(
const Exception &e)
1973 catch(
const Exception &e)
1997 InfoPanel->Caption =
"PRE-START: Select AUTOMATIC SIGNAL ROUTE start signal, or left click points to change manually";
1999 InfoPanel->Caption =
"OPERATING: Select AUTOMATIC SIGNAL ROUTE start signal, or left click points to change manually";
2007 catch(
const Exception &e)
2031 InfoPanel->Caption =
"PRE-START: Select PREFERRED ROUTE start signal, or left click points to change manually";
2033 InfoPanel->Caption =
"OPERATING: Select PREFERRED ROUTE start signal, or left click points to change manually";
2041 catch(
const Exception &e)
2071 InfoPanel->Caption =
"PRE-START: Select UNRESTRICTED ROUTE start location, or left click points to change manually";
2073 InfoPanel->Caption =
"OPERATING: Select UNRESTRICTED ROUTE start location, or left click points to change manually";
2081 catch(
const Exception &e)
2096 InfoPanel->Caption =
"ROUTE CANCELLING: Right click on truncate element, first element to cancel (anywhere else to skip)";
2103 catch(
const Exception &e)
2130 catch(
const Exception &e)
2144 UnicodeString MessageStr =
"Please note that the session will be lost if it hasn't been saved. Do you still wish to exit?";
2147 int button = Application->MessageBox(MessageStr.c_str(), L
"Please confirm", MB_YESNO);
2184 catch(
const Exception &e)
2221 catch(
const Exception &e)
2233 Screen->Cursor = TCursor(-11);
2234 std::ifstream VecFile(LoadFileName.c_str());
2235 if(!(VecFile.fail()))
2240 bool GraphicsFollow =
false;
2259 TFont *TempFont =
new TFont;
2260 TempFont->Style.Clear();
2261 TempFont->Name =
"MS Sans Serif";
2262 TempFont->Size = 10;
2264 TempFont->Charset = (TFontCharset)(0);
2273 if((LeftExcess > 0) && (RightExcess > 0))
2275 else if((LeftExcess > 0) && (RightExcess <= 0))
2278 else if((LeftExcess <= 0) && (RightExcess > 0))
2286 if((TopExcess > 0) && (BotExcess > 0))
2288 else if((TopExcess > 0) && (BotExcess <= 0))
2291 else if((TopExcess <= 0) && (BotExcess > 0))
2303 if((LastChar ==
'y') || (LastChar ==
'Y'))
2307 ShowMessage(
"Railway not ready for operation so unable to load as a .rly file. Loading as a new railway under development");
2314 Screen->Cursor = TCursor(-2);
2347 ShowMessage(
"File open failed prior to load");
2348 Screen->Cursor = TCursor(-2);
2351 ShowMessage(
"File integrity check failed - unable to load");
2366 Screen->Cursor = TCursor(-11);
2368 if(!(VecFile.fail()))
2395 ShowMessage(
"File open failed prior to save");
2396 Screen->Cursor = TCursor(-2);
2401 catch(
const Exception &e)
2417 catch(
const Exception &e)
2433 ShowMessage(
"Failed to find folder " +
IMAGE_DIR_NAME +
" in the folder where 'railway.exe' resides. Image can't be saved");
2437 Screen->Cursor = TCursor(-11);
2440 AnsiString ImageFileName = TDateTime::CurrentDateTime().FormatString(
"dd-mm-yyyy hh.nn.ss");
2444 AnsiString ShortName =
"";
2445 for(
int x = ImageFileName.Length(); x > 0; x--)
2447 if(ImageFileName[x] ==
'\\')
2449 ShortName = ImageFileName.SubString(x + 1, ImageFileName.Length() - x - 4);
2453 ShowMessage(
"A bitmap file named " + ShortName +
" will be created in the Images folder");
2454 Graphics::TBitmap *RailwayImage =
new Graphics::TBitmap;
2455 RailwayImage->PixelFormat = pf8bit;
2461 RailwayImage->Width = HPosMax - HPosMin;
2462 RailwayImage->Height = VPosMax - VPosMin;
2470 int NewWidth = (TextPtr->HPos - HPosMin) + (abs(TextPtr->Font->Height) * TextPtr->TextString.Length() * 0.7);
2471 int NewHeight = (TextPtr->VPos - VPosMin) + (abs(TextPtr->Font->Height) * 1.5);
2472 if(NewWidth > RailwayImage->Width)
2474 RailwayImage->Width = NewWidth;
2476 if(NewHeight > RailwayImage->Height)
2478 RailwayImage->Height = NewHeight;
2483 RailwayImage->Canvas->Brush->Color =
clB5G5R5;
2484 TRect Rect(0, 0, RailwayImage->Width, RailwayImage->Height);
2485 RailwayImage->Canvas->FillRect(Rect);
2493 RailwayImage->SaveToFile(ImageFileName);
2494 delete RailwayImage;
2497 Screen->Cursor = TCursor(-2);
2500 catch(
const Exception &e)
2502 if(e.Message.Pos(
"torage") > 0)
2504 Screen->Cursor = TCursor(-2);
2505 UnicodeString MessageStr =
"Insufficient memory available to store this image";
2506 Application->MessageBox(MessageStr.c_str(), L
"", MB_OK | MB_ICONWARNING);
2525 ShowMessage(
"Failed to find folder " +
IMAGE_DIR_NAME +
" in the folder where 'railway.exe' resides. Image can't be saved");
2529 Screen->Cursor = TCursor(-11);
2532 AnsiString ImageFileName = TDateTime::CurrentDateTime().FormatString(
"dd-mm-yyyy hh.nn.ss");
2536 AnsiString ShortName =
"";
2537 for(
int x = ImageFileName.Length(); x > 0; x--)
2539 if(ImageFileName[x] ==
'\\')
2541 ShortName = ImageFileName.SubString(x + 1, ImageFileName.Length() - x - 4);
2545 ShowMessage(
"A bitmap file named " + ShortName +
" will be created in the Images folder");
2546 Graphics::TBitmap *RailwayImage =
new Graphics::TBitmap;
2547 RailwayImage->PixelFormat = pf8bit;
2552 RailwayImage->Width = HPosMax - HPosMin;
2553 RailwayImage->Height = VPosMax - VPosMin;
2561 int NewWidth = (TextPtr->HPos - HPosMin) + (abs(TextPtr->Font->Height) * TextPtr->TextString.Length() * 0.7);
2562 int NewHeight = (TextPtr->VPos - VPosMin) + (abs(TextPtr->Font->Height) * 1.5);
2563 if(NewWidth > RailwayImage->Width)
2565 RailwayImage->Width = NewWidth;
2567 if(NewHeight > RailwayImage->Height)
2569 RailwayImage->Height = NewHeight;
2574 RailwayImage->Canvas->Brush->Color =
clB5G5R5;
2575 TRect Rect(0, 0, RailwayImage->Width, RailwayImage->Height);
2576 RailwayImage->Canvas->FillRect(Rect);
2579 for(
int x = 0; x < ((RailwayImage->Width) / 16); x++)
2581 for(
int y = 0; y < ((RailwayImage->Height) / 16); y++)
2591 RailwayImage->SaveToFile(ImageFileName);
2592 delete RailwayImage;
2595 Screen->Cursor = TCursor(-2);
2598 catch(
const Exception &e)
2600 if(e.Message.Pos(
"torage") > 0)
2602 Screen->Cursor = TCursor(-2);
2603 UnicodeString MessageStr =
"Insufficient memory available to store this image";
2604 Application->MessageBox(MessageStr.c_str(), L
"", MB_OK | MB_ICONWARNING);
2622 ShowMessage(
"Failed to find folder " +
IMAGE_DIR_NAME +
" in the folder where 'railway.exe' resides. Image can't be saved");
2626 Screen->Cursor = TCursor(-11);
2629 AnsiString ImageFileName = TDateTime::CurrentDateTime().FormatString(
"dd-mm-yyyy hh.nn.ss");
2633 AnsiString ShortName =
"";
2634 for(
int x = ImageFileName.Length(); x > 0; x--)
2636 if(ImageFileName[x] ==
'\\')
2638 ShortName = ImageFileName.SubString(x + 1, ImageFileName.Length() - x - 4);
2642 ShowMessage(
"A bitmap file named " + ShortName +
" will be created in the Images folder");
2643 Graphics::TBitmap *RailwayImage =
new Graphics::TBitmap;
2644 RailwayImage->PixelFormat = pf8bit;
2649 RailwayImage->Width = HPosMax - HPosMin;
2650 RailwayImage->Height = VPosMax - VPosMin;
2658 int NewWidth = (TextPtr->HPos - HPosMin) + (abs(TextPtr->Font->Height) * TextPtr->TextString.Length() * 0.7);
2659 int NewHeight = (TextPtr->VPos - VPosMin) + (abs(TextPtr->Font->Height) * 1.5);
2660 if(NewWidth > RailwayImage->Width)
2662 RailwayImage->Width = NewWidth;
2664 if(NewHeight > RailwayImage->Height)
2666 RailwayImage->Height = NewHeight;
2671 RailwayImage->Canvas->Brush->Color =
clB5G5R5;
2672 TRect Rect(0, 0, RailwayImage->Width, RailwayImage->Height);
2673 RailwayImage->Canvas->FillRect(Rect);
2681 RailwayImage->SaveToFile(ImageFileName);
2682 delete RailwayImage;
2685 Screen->Cursor = TCursor(-2);
2688 catch(
const Exception &e)
2690 if(e.Message.Pos(
"torage") > 0)
2692 Screen->Cursor = TCursor(-2);
2693 UnicodeString MessageStr =
"Insufficient memory available to store this image";
2694 Application->MessageBox(MessageStr.c_str(), L
"", MB_OK | MB_ICONWARNING);
2712 ShowMessage(
"Failed to find folder " +
IMAGE_DIR_NAME +
" in the folder where 'railway.exe' resides. Image can't be saved");
2716 Screen->Cursor = TCursor(-11);
2721 TimetableTimeStr = TimetableTimeStr.SubString(1, 2) +
'.' + TimetableTimeStr.SubString(4, 2) +
'.' + TimetableTimeStr.SubString(7, 2);
2722 AnsiString ImageFileName = TDateTime::CurrentDateTime().FormatString(
"dd-mm-yyyy hh.nn.ss");
2727 AnsiString ShortName =
"";
2728 for(
int x = ImageFileName.Length(); x > 0; x--)
2730 if(ImageFileName[x] ==
'\\')
2732 ShortName = ImageFileName.SubString(x + 1, ImageFileName.Length() - x - 4);
2736 ShowMessage(
"A bitmap file named " + ShortName +
" will be created in the Images folder");
2737 Graphics::TBitmap *RailwayImage =
new Graphics::TBitmap;
2738 RailwayImage->PixelFormat = pf8bit;
2743 RailwayImage->Width = HPosMax - HPosMin;
2744 RailwayImage->Height = VPosMax - VPosMin;
2752 int NewWidth = (TextPtr->HPos - HPosMin) + (abs(TextPtr->Font->Height) * TextPtr->TextString.Length() * 0.7);
2753 int NewHeight = (TextPtr->VPos - VPosMin) + (abs(TextPtr->Font->Height) * 1.5);
2754 if(NewWidth > RailwayImage->Width)
2756 RailwayImage->Width = NewWidth;
2758 if(NewHeight > RailwayImage->Height)
2760 RailwayImage->Height = NewHeight;
2765 RailwayImage->Canvas->Brush->Color =
clB5G5R5;
2766 TRect Rect(0, 0, RailwayImage->Width, RailwayImage->Height);
2767 RailwayImage->Canvas->FillRect(Rect);
2782 bool BreakFlag =
false;
2808 RailwayImage->SaveToFile(ImageFileName);
2809 delete RailwayImage;
2812 Screen->Cursor = TCursor(-2);
2815 catch(
const Exception &e)
2817 if(e.Message.Pos(
"torage") > 0)
2819 Screen->Cursor = TCursor(-2);
2820 UnicodeString MessageStr =
"Insufficient memory available to store this image";
2821 Application->MessageBox(MessageStr.c_str(), L
"", MB_OK | MB_ICONWARNING);
2849 Screen->Cursor = TCursor(-11);
2851 if(!(VecFile.fail()))
2878 ShowMessage(
"Railway failed to save - can't open file");
2879 Screen->Cursor = TCursor(-2);
2883 catch(
const Exception &e)
2897 catch(
const Exception &e)
2917 catch(
const Exception &e)
2932 ShowMessage(
"Failed to find folder " +
FORMATTEDTT_DIR_NAME +
" in the folder where 'railway.exe' resides. Timetable can't be exported");
2940 Screen->Cursor = TCursor(-2);
2943 catch(
const Exception &e)
3002 AZOrderButton->Hint = AnsiString(
"Arrange services in alphabetical order Toggle with Shift+ Z");
3019 ActiveTrackElementNameMapEntry.first =
Track->
TrackVector.at(x).ActiveTrackElementName;
3020 ActiveTrackElementNameMapEntry.second = 0;
3070 catch(
const Exception &e)
3113 if(TTBLFile.is_open())
3117 while(!TTBLFile.eof())
3120 if((c < 32) && (c != 13) && (c != 10) && (c !=
'\0'))
3122 ShowMessage(
"Timetable file is empty or contains non-ascii characters, codes must be between 20 and 127, or CR or LF");
3132 ShowMessage(
"Failed to open timetable file, make sure it's not open in another application");
3139 if(TTBLFile.is_open())
3148 AZOrderButton->Hint = AnsiString(
"Arrange services in alphabetical order Toggle with Shift+ Z");
3161 char *TimetableEntryString =
new char[10000];
3164 TTBLFile.getline(TimetableEntryString, 10000,
'\0');
3165 if(TTBLFile.eof() && (TimetableEntryString[0] ==
'\0'))
3170 AnsiString OneLine(TimetableEntryString);
3174 delete TimetableEntryString;
3179 ShowMessage(
"Failed to open timetable file, make sure it's not open in another application");
3215 ActiveTrackElementNameMapEntry.first =
Track->
TrackVector.at(x).ActiveTrackElementName;
3216 ActiveTrackElementNameMapEntry.second = 0;
3241 catch(
const Exception &e)
3259 InfoPanel->Caption =
"Timetable mode: editor hidden";
3265 ShowHideTTButton->Hint =
"Hide the timetable editor to see the railway Shift H";
3270 catch(
const Exception &e)
3309 catch(
const Exception &e)
3348 catch(
const Exception &e)
3368 catch(
const Exception &e)
3381 bool ValidFlag =
true;
3400 TDateTime DummyTime;
3418 ShowMessage(
"One or more times excessive, not permitted to exceed 95 hours");
3422 AnsiString MinsStr = AnsiString(Mins), HrsStr = AnsiString(Hrs);
3424 MinsStr =
"0" + MinsStr;
3426 HrsStr =
"0" + HrsStr;
3429 NewString += HrsStr +
':' + MinsStr;
3446 catch(
const Exception &e)
3459 bool ValidFlag =
true;
3478 TDateTime DummyTime;
3496 ShowMessage(
"One or more times are now before 00:00, this is not permitted");
3500 AnsiString MinsStr = AnsiString(Mins), HrsStr = AnsiString(Hrs);
3502 MinsStr =
"0" + MinsStr;
3504 HrsStr =
"0" + HrsStr;
3507 NewString += HrsStr +
':' + MinsStr;
3523 catch(
const Exception &e)
3561 catch(
const Exception &e)
3607 if(OldVectorPos == 0)
3635 catch(
const Exception &e)
3694 catch(
const Exception &e)
3712 UnicodeString MessageStr =
"Are you sure this entry should be deleted?";
3713 int button = Application->MessageBox(MessageStr.c_str(), L
"Please confirm", MB_YESNO);
3745 if(OldVectorPos == 0)
3773 catch(
const Exception &e)
3794 AnsiString TempStr =
"";
3795 bool ActiveLine =
false;
3820 while(TempStr[TempStr.Length()] ==
',')
3822 TempStr = TempStr.SubString(1, TempStr.Length() - 1);
3851 (*TTCurrentEntryPtr) = TempStr;
3921 catch(
const Exception &e)
3936 ShowMessage(
"Timetable is empty, can't save an empty timetable");
3940 std::ofstream TTBLFile;
3970 if(TTBLFile.is_open())
3974 TTBLFile << (*TEVPtr).c_str() <<
'\0';
3981 ShowMessage(
CreateEditTTFileName +
" failed to open, ensure not already open in another application");
3987 catch(
const Exception &e)
4002 ShowMessage(
"Timetable is empty, can't save an empty timetable");
4006 std::ofstream TTBLFile;
4010 for(
int x =
SaveTTDialog->FileName.Length(); x > 0; x--)
4028 if(TTBLFile.is_open())
4032 TTBLFile << (*TEVPtr).c_str() <<
'\0';
4039 ShowMessage(
CreateEditTTFileName +
" failed to open, ensure not already open in another application");
4045 catch(
const Exception &e)
4059 bool EndOfFile =
false;
4060 bool FinalCallFalse =
false;
4061 bool GiveMessagesTrue =
true;
4062 bool CheckLocationsExistInRailway =
false;
4064 CheckLocationsExistInRailway =
true;
4070 "The basic syntax seems OK but this check is very limited. Other aspects can only be checked by validating the whole timetable with the appropriate railway (.rly) loaded");
4076 catch(
const Exception &e)
4104 bool CheckLocationsExistInRailwayTrue =
true;
4107 Screen->Cursor = TCursor(-11);
4109 if(TTBLFile.is_open())
4113 ShowMessage(
"Timetable integrity OK");
4120 ShowMessage(
"Failed to open timetable file, make sure it's not open in another application");
4122 Screen->Cursor = TCursor(-2);
4132 catch(
const Exception &e)
4156 AnsiString TempStr = *
TEVPtr;
4194 catch(
const Exception &e)
4218 AnsiString TempStr = *
TEVPtr;
4256 catch(
const Exception &e)
4293 catch(
const Exception &e)
4308 UnicodeString MessageStr =
"All changes to the timetable will be lost - proceed?";
4309 int button = Application->MessageBox(MessageStr.c_str(), L
"Please confirm", MB_YESNO);
4320 if(TTBLFile.is_open())
4337 char *TimetableEntryString =
new char[10000];
4340 TTBLFile.getline(TimetableEntryString, 10000,
'\0');
4341 if(TTBLFile.eof() && (TimetableEntryString[0] ==
'\0'))
4346 AnsiString OneLine(TimetableEntryString);
4350 delete TimetableEntryString;
4355 ShowMessage(
"Failed to open timetable file, make sure it's not open in another application");
4376 catch(
const Exception &e)
4391 ShowMessage(
"Failed to find folder " +
FORMATTEDTT_DIR_NAME +
" in the folder where 'railway.exe' resides. Timetable can't be exported");
4410 Screen->Cursor = TCursor(-2);
4415 catch(
const Exception &e)
4448 catch(
const Exception &e)
4463 UnicodeString MessageStr =
"The timetable has changed.\n\nAre you sure you want to exit without saving it?";
4464 int button = Application->MessageBox(MessageStr.c_str(), L
"Please confirm", MB_YESNO);
4480 catch(
const Exception &e)
4508 catch(
const Exception &e)
4533 catch(
const Exception &e)
4551 catch(
const Exception &e)
4574 catch(
const Exception &e)
4583 TShiftState Shift,
int X,
int Y)
4627 catch(
const Exception &e)
4656 if((TopPos + (Y / 13)) >=
OAListBox->Items->Count)
4664 std::advance(OACurrentEntryPtr, ((Y / 13) + TopPos));
4668 int TrackVectorPosition;
4669 int TrainIDorTVPos = OACurrentEntryPtr->second.second;
4670 if(TrainIDorTVPos >= 0)
4686 TrackVectorPosition = -(TrainIDorTVPos + 1);
4701 TPoint MainScreenPoint(ScreenPosH + 8, ScreenPosV + 8);
4702 TPoint CursPos =
MainScreen->ClientToScreen(MainScreenPoint);
4703 Mouse->CursorPos = CursPos;
4706 catch(
const Exception &e)
4718 PreStartTime, ActiveSegment, PostEnd} Segment;
4731 Segment = PreStartTime;
4734 if(Segment == PreStartTime)
4741 Segment = ActiveSegment;
4752 AnsiString CurrentStr = *
TEVPtr;
4753 if(CurrentStr !=
"")
4755 CurrentStr = CurrentStr.SubString(1, 10);
4756 for(
int x = 1; x < CurrentStr.Length(); x++)
4758 if((CurrentStr[x] < 32) || (CurrentStr[1] > 126))
4760 CurrentStr = CurrentStr.SubString(1, (x - 1));
4769 if(Segment == ActiveSegment)
4784 AnsiString Entry = *
TEVPtr;
4789 int SCPos = Entry.Pos(
';');
4790 int CPos = Entry.Pos(
',');
4797 if((CPos == 0) && (SCPos == 0))
4799 Entry = Entry.SubString(1, 12);
4801 else if((CPos > 0) && (SCPos > 0) && (CPos < SCPos))
4803 Entry = Entry.SubString(1, CPos - 1);
4805 else if((CPos > 0) && (SCPos > 0) && (CPos > SCPos))
4807 Entry = Entry.SubString(1, SCPos - 1);
4809 else if((CPos > 0) && (SCPos == 0))
4811 Entry = Entry.SubString(1, CPos - 1);
4815 Entry = Entry.SubString(1, SCPos - 1);
4828 if(Segment == PostEnd)
4836 AnsiString CurrentStr = *
TEVPtr;
4837 if(CurrentStr !=
"")
4839 CurrentStr = CurrentStr.SubString(1, 10);
4840 for(
int x = 1; x < CurrentStr.Length(); x++)
4842 if((CurrentStr[x] < 32) || (CurrentStr[1] > 126))
4844 CurrentStr = CurrentStr.SubString(1, (x - 1));
4875 UnicodeString MessageStr =
4876 "If you wish to preserve the original order don't make any changes whilst in alphabetical order.\n\nIn that case use alphabetical order to find the service required, click it to display it, then revert to the original order where the same service will be displayed and can be changed.";
4877 Application->MessageBox(MessageStr.c_str(), L
"Please Note:", MB_OK | MB_ICONWARNING);
4890 std::sort(SortStart, SortEnd);
4892 bool CurrentEntryChanged =
false;
4898 CurrentEntryChanged =
true;
4901 if(!CurrentEntryChanged)
4906 AZOrderButton->Hint = AnsiString(
"Arrange services in original order Toggle with Shift+ Z");
4912 UnicodeString MessageStr =
4913 "Reverting to the original order will discard any changes made whilst in alphabetical order.\n\nTo preserve the changes click 'No', then save the timetable or use 'save as' if you wish to keep the original timetable.\n\nDo you wish to proceed?";
4914 int button = Application->MessageBox(MessageStr.c_str(), L
"Warning!", MB_YESNO | MB_ICONWARNING);
4928 bool CurrentEntryChanged =
false;
4934 CurrentEntryChanged =
true;
4937 if(!CurrentEntryChanged)
4942 AZOrderButton->Hint = AnsiString(
"Arrange services in alphabetical order Toggle with Shift+ Z");
4951 catch(
const Exception &e)
4962 AnsiString OutStr =
"";
4965 while(x < ConvStr.Length())
4967 if((ConvStr[x] ==
'\r') && (ConvStr[x + 1] ==
'\n'))
4975 OutStr += ConvStr[x];
4979 if(x == ConvStr.Length())
4980 OutStr += ConvStr[x];
4985 while(OutStr[OutStr.Length()] ==
',')
4987 OutStr = OutStr.SubString(1, OutStr.Length() - 1);
5057 InfoPanel->Caption =
"Select option or change entry";
5071 bool ValidFlag =
true;
5072 for(
int x = 1; x <= AnsiAddSubText.Length(); x++)
5074 if((AnsiAddSubText[x] >
'9') || (AnsiAddSubText[x] <
'0'))
5082 if(AnsiAddSubText.ToInt() != 0)
5154 bool ServiceEntry =
true;
5159 bool ServiceEntry =
false;
5171 InfoPanel->Caption =
"Add or change entry then save it, or cancel";
5181 AnsiString((
short)ServiceEntry));
5188 int CommaPos = Data.Pos(
',');
5189 if((CommaPos == 0) && (Data !=
""))
5191 CommaPos = Data.Length() + 1;
5194 if(Data.Length() <= CommaPos)
5196 Data = Data.SubString(CommaPos + 1, Data.Length() - CommaPos);
5233 if(CurrentStr !=
"")
5235 for(
int x = 1; x < CurrentStr.Length(); x++)
5237 if((CurrentStr[x] < 32) || (CurrentStr[1] > 126))
5239 CurrentStr = CurrentStr.SubString(1, (x - 1));
5264 TDateTime DummyTime;
5265 bool TimesPresent =
false;
5273 TimesPresent =
true;
5280 return TimesPresent;
5294 UnicodeString MessageStr =
5295 "Note that leaving the track unlinked will cause preferred directions to be lost on reloading. Prevent by linking the track then resaving. Do you still wish to exit?";
5296 int button = Application->MessageBox(MessageStr.c_str(), L
"Please confirm", MB_YESNO);
5305 UnicodeString MessageStr =
"The railway has changed, exit without saving?";
5306 int button = Application->MessageBox(MessageStr.c_str(), L
"Please confirm", MB_YESNO);
5318 Application->Terminate();
5320 catch(
const Exception &e)
5343 catch(
const Exception &e)
5366 catch(
const Exception &e)
5389 catch(
const Exception &e)
5448 catch(
const Exception &e)
5466 catch(
const Exception &e)
5485 catch(
const Exception &e)
5520 catch(
const Exception &e)
5531 TrainController->
LogEvent(
"MainScreenMouseDown2," + AnsiString(Button) +
"," + AnsiString(X) +
"," + AnsiString(Y));
5533 "," + AnsiString(Y));
5544 int NoOffsetX, NoOffsetY;
5546 if(Button == mbRight)
5550 AnsiString Text =
"";
5557 Screen->Cursor = TCursor(-22);
5608 bool TrackEraseSuccessfulFlag;
5609 int ErasedTrackVectorPosition;
5610 Screen->Cursor = TCursor(-11);
5612 if(TrackEraseSuccessfulFlag)
5614 if(ErasedTrackVectorPosition > -1)
5645 Screen->Cursor = TCursor(-2);
5653 bool LeadingPointsAtLastElement =
false;
5668 if(!LeadingPointsAtLastElement)
5673 InfoPanel->Caption =
"DISTANCE/SPEED SETTING: Continue or set values (overall length), or right click to cancel/truncate";
5688 InfoPanel->Caption =
"DISTANCE/SPEED SETTING: Can't end on leading points, continue or truncate";
5765 if((TrainID01 > -1) && (TrainID23 > -1))
5815 AnsiString LocName =
"";
5820 if((LocName ==
"") && (Train.
MidElement > -1))
5934 Screen->Cursor = TCursor(-11);
5945 Screen->Cursor = TCursor(-2);
6012 Screen->Cursor = TCursor(-11);
6014 bool TrackLinkingRequiredFlag;
6016 TSpeedButton *TempSpeedButton = 0;
6024 bool InternalChecks =
true;
6030 if(TrackLinkingRequiredFlag)
6059 Screen->Cursor = TCursor(-2);
6073 NewGI.
Width = UGMIt->second->Width;
6074 NewGI.
Height = UGMIt->second->Height;
6099 AnsiString NameString;
6109 unsigned int ValidPosition;
6120 ValidElement = InactiveTrackElement1;
6121 ValidPosition = InactivePair.first;
6126 ValidElement = InactiveTrackElement2;
6127 ValidPosition = InactivePair.second;
6138 InfoPanel->Caption =
"NAMING LOCATIONS: Enter name, 'Carriage Return' to accept, 'Escape' to quit";
6169 bool FinishElement =
false, LeadingPointsAtLastElement =
false;
6170 Screen->Cursor = TCursor(-11);
6184 InfoPanel->Caption =
"DISTANCE/SPEED SETTING: Set values (overall length), or right click to cancel/truncate";
6194 Screen->Cursor = TCursor(-2);
6200 if(!LeadingPointsAtLastElement)
6205 InfoPanel->Caption =
"DISTANCE/SPEED SETTING: Continue or set values (overall length), or right click to cancel/truncate";
6222 InfoPanel->Caption =
"DISTANCE/SPEED SETTING: Can't end on leading points, need to continue or truncate";
6237 Screen->Cursor = TCursor(-2);
6242 Screen->Cursor = TCursor(-2);
6259 InfoPanel->Caption =
"CONNECTING GAPS: Connecting element selected";
6271 ShowMessage(
"All gaps set");
6299 int TrueX = 0, TrueY = 0;
6300 AnsiString ExistingText =
"";
6302 TFont *ExistingTextFont =
new TFont;
6303 int ExistingTextHPos = 0, ExistingTextVPos = 0;
6309 if((TrueX >= TextPtr->HPos) && (TrueX < (TextPtr->HPos + abs(TextPtr->Font->Height))) && (TrueY >= TextPtr->VPos) && (TrueY <
6310 (TextPtr->VPos + abs(TextPtr->Font->Height))))
6312 ExistingText = TextPtr->TextString;
6313 ExistingTextFont->Assign(TextPtr->Font);
6314 ExistingTextHPos = TextPtr->HPos;
6315 ExistingTextVPos = TextPtr->VPos;
6327 TextBox->Font->Assign(ExistingTextFont);
6329 Text_X = ExistingTextHPos;
6330 Text_Y = ExistingTextVPos;
6345 TextBox->Text =
"New Text: CR=end, ESC=quit";
6348 delete ExistingTextFont;
6440 Screen->Cursor = TCursor(-11);
6449 ShowMessage(
"Preferred direction added");
6453 Screen->Cursor = TCursor(-2);
6472 Screen->Cursor = TCursor(-2);
6476 Screen->Cursor = TCursor(-2);
6573 AnsiString(PDE.
VLoc));
6586 bool PointsChanged =
false;
6587 IDInt ReqPosRouteID(-1);
6589 bool CallonTrue =
true;
6590 bool ConsecSignalsRouteFalse =
false;
6599 CallonTrue, ReqPosRouteID, PointsChanged))
6641 float TempSpeedVal = 1;
6709 int DivergingPosition = TrackElement.
Conn[3];
6711 DivergingPosition)))
6786 InfoPanel->Caption =
"PRE-START: Select next route location";
6788 InfoPanel->Caption =
"OPERATING: Select next route location";
6800 bool CallonFalse =
false;
6807 InfoPanel->Caption =
"PRE-START: Select next route location";
6809 InfoPanel->Caption =
"OPERATING: Select next route location";
6827 Screen->Cursor = TCursor(-11);
6829 bool PointsChanged =
false;
6839 float TempSpeedVal = 1;
6844 else if(PointsChanged)
6855 Screen->Cursor = TCursor(-2);
6863 bool CallonFalse =
false;
6869 float TempSpeedVal = 1;
6874 else if(PointsChanged)
6888 Screen->Cursor = TCursor(-2);
6897 catch(
const Exception &e)
6911 TrainController->
LogEvent(
"MainScreenMouseDown3," + AnsiString(Button) +
"," + AnsiString(X) +
"," + AnsiString(Y));
6913 "," + AnsiString(Y));
6914 if(Button != mbLeft)
6920 Screen->Cursor = TCursor(-22);
6926 int HRounding, VRounding;
6977 else if(TempLevel2OperMode ==
Operating)
6980 OperateButton->Glyph->LoadFromResourceName(0,
"PauseGraphic");
6984 else if(TempLevel2OperMode ==
Paused)
6987 OperateButton->Glyph->LoadFromResourceName(0,
"RunGraphic");
6993 else if(TempLevel2OperMode ==
PreStart)
6996 OperateButton->Glyph->LoadFromResourceName(0,
"RunGraphic");
7007 catch(
const Exception &e)
7097 if(CurrentHLoc >= StartHLoc)
7101 if(CurrentVLoc >= StartVLoc)
7113 TRect TempRect(StartHLoc, StartVLoc, CurrentHLoc, CurrentVLoc);
7127 if(CurrentHLoc >= StartHLoc)
7131 if(CurrentVLoc >= StartVLoc)
7143 TRect TempRect(StartHLoc, StartVLoc, CurrentHLoc, CurrentVLoc);
7202 catch(
const Exception &e)
7238 TrainController->
LogEvent(
"MainScreenMouseUp," + AnsiString(Button) +
"," + AnsiString(X) +
"," + AnsiString(Y));
7241 Screen->Cursor = TCursor(-2);
7245 Screen->Cursor = TCursor(-11);
7250 if(EndHLoc >= StartHLoc)
7254 if(EndVLoc >= StartVLoc)
7258 if(StartHLoc >= EndHLoc)
7268 if(StartVLoc >= EndVLoc)
7294 Screen->Cursor = TCursor(-2);
7360 if(IATVecPair.second != IATVecPair.first)
7378 if((TextPtr->HPos >= LowSelectHPos) && (TextPtr->HPos < HighSelectHPos) && (TextPtr->VPos >= LowSelectVPos) && (TextPtr->VPos <
7386 bool SelectVectorNamedElement =
false;
7387 AnsiString SelectTextString;
7392 SelectVectorNamedElement =
true;
7396 if(SelectVectorNamedElement)
7398 SelectTextString =
"##**" + TextPtr->TextString;
7402 SelectTextString = TextPtr->TextString;
7404 TTextItem TextItem(TextPtr->HPos, TextPtr->VPos, SelectTextString, TextPtr->Font);
7413 for(TTrack::TUserGraphicVector::iterator UserGraphicPtr =
Track->
UserGraphicVector.begin(); UserGraphicPtr < Track->UserGraphicVector.end();
7416 if((UserGraphicPtr->HPos >= LowSelectHPos) && ((UserGraphicPtr->HPos + UserGraphicPtr->Width) < HighSelectHPos) &&
7417 (UserGraphicPtr->VPos >= LowSelectVPos) && ((UserGraphicPtr->VPos + UserGraphicPtr->Height) < HighSelectVPos))
7430 Screen->Cursor = TCursor(-2);
7436 Screen->Cursor = TCursor(-11);
7442 if(EndHLoc >= StartHLoc)
7446 if(EndVLoc >= StartVLoc)
7450 if(StartHLoc >= EndHLoc)
7460 if(StartVLoc >= EndVLoc)
7485 Screen->Cursor = TCursor(-2);
7514 Screen->Cursor = TCursor(-2);
7540 catch(
const Exception &e)
7573 throw Exception(
"Warning - Utilities->CallLog contains more than 50 items");
7600 catch(
const Exception &e)
7680 if(
WholeRailwayMoving && (GetAsyncKeyState(VK_LBUTTON) >= 0) && (GetAsyncKeyState(VK_RBUTTON) >= 0))
7683 Screen->Cursor = TCursor(-2);
7710 bool TrainPresent =
false;
7724 TDateTime TempExcessLCDownTime;
7729 if(TempExcessLCDownTime > TDateTime(0))
7757 bool ElementRemovedFlag =
false;
7768 ElementRemovedFlag =
true;
7780 bool WH1 = (Mouse->CursorPos.x >= ClientOrigin.x +
OutputLog1->Left) && (Mouse->CursorPos.x < (ClientOrigin.x +
OutputLog1->Width +
OutputLog1->Left))
7783 bool WH2 = (Mouse->CursorPos.x >= ClientOrigin.x +
OutputLog2->Left) && (Mouse->CursorPos.x < (ClientOrigin.x +
OutputLog2->Width +
OutputLog2->Left))
7786 bool WH3 = (Mouse->CursorPos.x >= ClientOrigin.x +
OutputLog3->Left) && (Mouse->CursorPos.x < (ClientOrigin.x +
OutputLog3->Width +
OutputLog3->Left))
7789 bool WH4 = (Mouse->CursorPos.x >= ClientOrigin.x +
OutputLog4->Left) && (Mouse->CursorPos.x < (ClientOrigin.x +
OutputLog4->Width +
OutputLog4->Left))
7792 bool WH5 = (Mouse->CursorPos.x >= ClientOrigin.x +
OutputLog5->Left) && (Mouse->CursorPos.x < (ClientOrigin.x +
OutputLog5->Width +
OutputLog5->Left))
7795 bool WH6 = (Mouse->CursorPos.x >= ClientOrigin.x +
OutputLog6->Left) && (Mouse->CursorPos.x < (ClientOrigin.x +
OutputLog6->Width +
OutputLog6->Left))
7798 bool WH7 = (Mouse->CursorPos.x >= ClientOrigin.x +
OutputLog7->Left) && (Mouse->CursorPos.x < (ClientOrigin.x +
OutputLog7->Width +
OutputLog7->Left))
7801 bool WH8 = (Mouse->CursorPos.x >= ClientOrigin.x +
OutputLog8->Left) && (Mouse->CursorPos.x < (ClientOrigin.x +
OutputLog8->Width +
OutputLog8->Left))
7804 bool WH9 = (Mouse->CursorPos.x >= ClientOrigin.x +
OutputLog9->Left) && (Mouse->CursorPos.x < (ClientOrigin.x +
OutputLog9->Width +
OutputLog9->Left))
7807 bool WH10 = (Mouse->CursorPos.x >= ClientOrigin.x +
OutputLog10->Left) &&
7811 if(WH1 || WH2 || WH3 || WH4 || WH5 || WH6 || WH7 || WH8 || WH9 || WH10)
7832 AnsiString Type[15] =
7833 {
"Simple",
"Crossover",
"Points",
"Buffers",
"Bridge",
"SignalPost",
"Continuation",
"Platform",
"GapJump",
"FootCrossing",
"Unused",
"Concourse",
7834 "Parapet",
"NamedNonStationLocation",
"Erase"};
7836 int ScreenX = Mouse->CursorPos.x -
MainScreen->ClientOrigin.x;
7837 int ScreenY = Mouse->CursorPos.y -
MainScreen->ClientOrigin.y;
7839 AnsiString MouseStr =
"Posx: " + AnsiString(ScreenX) +
"; Posy: " + AnsiString(ScreenY);
7844 DevelopmentPanel->Caption = MouseStr +
"; TVPos: " + AnsiString(Position) +
"; H: " + AnsiString(HLoc) +
"; V: " + AnsiString(VLoc) +
7845 "; SpTg: " + AnsiString(TrackElement.
SpeedTag) +
"; Type: " + Type[TrackElement.
TrackType] +
"; Att: " + AnsiString(TrackElement.
Attribute)
7863 if((GetKeyState(VK_LBUTTON) >= 0) && (GetKeyState(VK_RBUTTON) >= 0) && (
TTCurrentEntryPtr > 0))
7994 Screen->Cursor = TCursor(-11);
8150 int RouteStartVecPos;
8160 if(FoundFlag && (RouteStartVecPos > -1))
8176 catch(
const Exception &e)
8194 InfoPanel->Caption =
"CALLING ON: Select signal for call on";
8208 catch(
const Exception &e)
8222 Screen->Cursor = TCursor(-11);
8264 Screen->Cursor = TCursor(-2);
8267 catch(
const Exception &e)
8281 Screen->Cursor = TCursor(-11);
8323 Screen->Cursor = TCursor(-2);
8326 catch(
const Exception &e)
8340 Screen->Cursor = TCursor(-11);
8383 Screen->Cursor = TCursor(-2);
8386 catch(
const Exception &e)
8400 Screen->Cursor = TCursor(-11);
8442 Screen->Cursor = TCursor(-2);
8445 catch(
const Exception &e)
8459 Screen->Cursor = TCursor(-11);
8496 OperateButton->Glyph->LoadFromResourceName(0,
"PauseGraphic");
8503 OperateButton->Glyph->LoadFromResourceName(0,
"RunGraphic");
8512 OperateButton->Glyph->LoadFromResourceName(0,
"RunGraphic");
8539 if((LeftExcess > 0) && (RightExcess > 0))
8541 else if((LeftExcess > 0) && (RightExcess <= 0))
8544 else if((LeftExcess <= 0) && (RightExcess > 0))
8552 if((TopExcess > 0) && (BotExcess > 0))
8554 else if((TopExcess > 0) && (BotExcess <= 0))
8557 else if((TopExcess <= 0) && (BotExcess > 0))
8567 ZoomButton->Glyph->LoadFromResourceName(0,
"ZoomIn");
8569 Screen->Cursor = TCursor(-2);
8573 catch(
const Exception &e)
8587 Screen->Cursor = TCursor(-11);
8610 Screen->Cursor = TCursor(-2);
8614 catch(
const Exception &e)
8642 catch(
const Exception &e)
8658 catch(
const Exception &e)
8685 catch(
const Exception &e)
8708 TRect NewSelectRect(TLHCH, TLHCV, BRHCH, BRHCV);
8741 catch(
const Exception &e)
8760 catch(
const Exception &e)
8779 catch(
const Exception &e)
8827 int MidVPosAfterFlip = ((VerSum * 16) + 15) - MidVPosBeforeFlip;
8835 catch(
const Exception &e)
8883 int MidHPosAfterMirror = ((HorSum * 16) + 15) - MidHPosBeforeMirror;
8885 if(LeftPosAfterMirror < (
SelectRect.left * 16))
8895 catch(
const Exception &e)
8948 int MidVPosAfterFlip = ((VerSum * 16) + 15) - MidVPosBeforeFlip;
8960 int MidHPosAfterMirror = ((HorSum * 16) + 15) - MidHPosBeforeMirror;
8962 if(LeftPosAfterMirror < (
SelectRect.left * 16))
8974 catch(
const Exception &e)
8987 Screen->Cursor = TCursor(-11);
9004 int button = Application->MessageBox
9005 (L
"Original selection adjusted to make it square. 'OK' to keep this selection or 'Cancel' to make a new selection",
9006 L
"Left click and hold here to move this message box", MB_OKCANCEL);
9007 if(button == IDCANCEL)
9015 Screen->Cursor = TCursor(-2);
9052 if(IATVecPair.second != IATVecPair.first)
9070 if((TextPtr->HPos >= LowSelectHPos) && (TextPtr->HPos < HighSelectHPos) && (TextPtr->VPos >= LowSelectVPos) && (TextPtr->VPos < HighSelectVPos))
9077 bool SelectVectorNamedElement =
false;
9078 AnsiString SelectTextString;
9083 SelectVectorNamedElement =
true;
9087 if(SelectVectorNamedElement)
9089 SelectTextString =
"##**" + TextPtr->TextString;
9093 SelectTextString = TextPtr->TextString;
9095 TTextItem TextItem(TextPtr->HPos, TextPtr->VPos, SelectTextString, TextPtr->Font);
9104 for(TTrack::TUserGraphicVector::iterator UserGraphicPtr =
Track->
UserGraphicVector.begin(); UserGraphicPtr < Track->UserGraphicVector.end();
9107 if((UserGraphicPtr->HPos >= LowSelectHPos) && ((UserGraphicPtr->HPos + UserGraphicPtr->Width) < HighSelectHPos) && (UserGraphicPtr->VPos >=
9108 LowSelectVPos) && ((UserGraphicPtr->VPos + UserGraphicPtr->Height) < HighSelectVPos))
9147 int MidHPosAfterRotate = ((
SelectRect.bottom * 16) - 1) + (
SelectRect.left * 16) - MidVPosBeforeRotate;
9154 Screen->Cursor = TCursor(-2);
9159 catch(
const Exception &e)
9173 Screen->Cursor = TCursor(-11);
9190 int button = Application->MessageBox
9191 (L
"Original selection adjusted to make it square. 'OK' to keep this selection or 'Cancel' to make a new selection",
9192 L
"Left click and hold here to move this message box", MB_OKCANCEL);
9193 if(button == IDCANCEL)
9201 Screen->Cursor = TCursor(-2);
9238 if(IATVecPair.second != IATVecPair.first)
9256 if((TextPtr->HPos >= LowSelectHPos) && (TextPtr->HPos < HighSelectHPos) && (TextPtr->VPos >= LowSelectVPos) && (TextPtr->VPos < HighSelectVPos))
9263 bool SelectVectorNamedElement =
false;
9264 AnsiString SelectTextString;
9269 SelectVectorNamedElement =
true;
9273 if(SelectVectorNamedElement)
9275 SelectTextString =
"##**" + TextPtr->TextString;
9279 SelectTextString = TextPtr->TextString;
9281 TTextItem TextItem(TextPtr->HPos, TextPtr->VPos, SelectTextString, TextPtr->Font);
9290 for(TTrack::TUserGraphicVector::iterator UserGraphicPtr =
Track->
UserGraphicVector.begin(); UserGraphicPtr < Track->UserGraphicVector.end();
9293 if((UserGraphicPtr->HPos >= LowSelectHPos) && ((UserGraphicPtr->HPos + UserGraphicPtr->Width) < HighSelectHPos) && (UserGraphicPtr->VPos >=
9294 LowSelectVPos) && ((UserGraphicPtr->VPos + UserGraphicPtr->Height) < HighSelectVPos))
9334 int MidVPosAfterRotate = ((
SelectRect.bottom * 16) - 1) + (
SelectRect.left * 16) - MidHPosBeforeRotate;
9340 Screen->Cursor = TCursor(-2);
9345 catch(
const Exception &e)
9365 catch(
const Exception &e)
9384 catch(
const Exception &e)
9402 InfoPanel->Caption =
"DISTANCE/SPEED SETTING: Set values or leave blank for no change";
9403 ShowMessage(
"Note: length value will apply to each element's track within the selection");
9411 catch(
const Exception &e)
9429 bool FoundFlag =
false;
9473 catch(
const Exception &e)
9503 catch(
const Exception &e)
9530 bool CheckLocationsExistInRailwayTrue =
true;
9534 Screen->Cursor = TCursor(-11);
9535 std::ifstream TTBLFile(AnsiString(
TimetableDialog->FileName).c_str(), std::ios_base::binary);
9536 if(TTBLFile.is_open())
9538 bool SessionFileFalse =
false;
9546 ShowMessage(
"Failed to open timetable file, make sure it's not open in another application");
9548 Screen->Cursor = TCursor(-2);
9551 ShowMessage(
"Timetable preliminary integrity check failed - unable to load");
9556 catch(
const Exception &e)
9581 AnsiString LocName =
"";
9586 if((LocName ==
"") && (Train.
MidElement > -1))
9606 if((NextElementPosition > -1) && (NextEntryPos > -1))
9621 if((LocName ==
"") && (Train.
MidElement > -1))
9628 catch(
const Exception &e)
9652 AnsiString LocName =
"";
9657 if((LocName ==
"") && (Train.
MidElement > -1))
9665 if((LocName ==
"") && (Train.
MidElement > -1))
9695 int NextElementPos = -1;
9696 int NextEntryPos = -1;
9712 if((NextElementPos > -1) && (NextEntryPos > -1))
9746 catch(
const Exception &e)
9764 AnsiString LocName =
"";
9769 if((LocName ==
"") && (Train.
MidElement > -1))
9777 if((LocName ==
"") && (Train.
MidElement > -1))
9784 catch(
const Exception &e)
9813 int NextElementPos = -1;
9814 int NextEntryPos = -1;
9820 if((NextElementPos > -1) && (NextEntryPos > -1))
9840 catch(
const Exception &e)
9853 TTrain *TrainToBeJoinedBy;
9866 ShowMessage(
"Can't join two trains when both are without power");
9870 AnsiString TrainToBeJoinedByHeadCode = TrainToBeJoinedBy->
HeadCode;
9872 double OtherBrakeForce = TrainToBeJoinedBy->
MaxBrakeRate * TrainToBeJoinedBy->
Mass;
9874 double CombinedBrakeRate = (OtherBrakeForce + OwnBrakeForce) / (TrainToBeJoinedBy->
Mass + ThisTrain.
Mass);
9875 ThisTrain.
Mass += TrainToBeJoinedBy->
Mass;
9882 AnsiString LocName =
"";
9887 if((LocName ==
"") && (ThisTrain.
MidElement > -1))
9895 if((LocName ==
"") && (ThisTrain.
MidElement > -1))
9929 catch(
const Exception &e)
9959 AnsiString LocName =
"";
9964 if((LocName ==
"") && (Train.
MidElement > -1))
9972 if((LocName ==
"") && (Train.
MidElement > -1))
9988 catch(
const Exception &e)
10019 catch(
const Exception &e)
10035 if(NextElementPos < 0)
10037 throw Exception(
"Error, no element in front in PassRedSignalMenuItemClick");
10048 throw Exception(
"Error, next element not a signal type in PassRedSignalMenuItemClick");
10062 catch(
const Exception &e)
10088 int NextElementPos = -1;
10090 int NextEntryPos = -1;
10096 if((NextElementPos > -1) && (NextEntryPos > -1))
10105 catch(
const Exception &e)
10124 UnicodeString Message = UnicodeString(Train.
HeadCode) +
" will be removed from the railway - proceed?";
10125 int button = Application->MessageBox(Message.c_str(), L
"Please confirm", MB_YESNO);
10138 AnsiString LocName =
"";
10143 if((LocName ==
"") && (Train.
MidElement > -1))
10151 if((LocName ==
"") && (Train.
MidElement > -1))
10249 catch(
const Exception &e)
10264 Application->Terminate();
10278 catch(
const Exception &e)
10292 UnicodeString MessageStr =
10293 "Note that leaving the track unlinked will cause preferred directions to be lost on reloading. Prevent by linking the track then resaving. Do you still wish to exit?";
10294 int button = Application->MessageBox(MessageStr.c_str(), L
"Please confirm", MB_YESNO);
10304 UnicodeString MessStr =
"";
10307 MessStr = UnicodeString(
"The railway and the timetable have both changed, exit without saving either?");
10311 MessStr = UnicodeString(
"The railway has changed, exit without saving?");
10315 MessStr = UnicodeString(
"The timetable has changed, exit without saving?");
10317 int button = Application->MessageBox(MessStr.c_str(), L
"Please confirm", MB_YESNO);
10328 UnicodeString MessageStr =
"Please note that the session will be lost if it hasn't been saved. Do you still wish to exit?";
10331 int button = Application->MessageBox(MessageStr.c_str(), L
"Please confirm", MB_YESNO);
10349 catch(
const Exception &e)
10363 if((Shift.Contains(ssAlt)) && (Shift.Contains(ssCtrl)))
10376 else if(Key ==
'3')
10388 else if(Key ==
'4')
10393 else if(Shift.Contains(ssCtrl) && !Shift.Contains(ssShift) && !Shift.Contains(ssAlt))
10397 else if(Shift.Contains(ssShift) && !Shift.Contains(ssCtrl) && !Shift.Contains(ssAlt))
10410 if((Key != VK_SHIFT) && (Key != VK_CONTROL))
10427 else if(Key == VK_DOWN)
10432 else if(Key == VK_LEFT)
10437 else if(Key == VK_RIGHT)
10442 else if(Key == VK_HOME)
10448 else if(Key == VK_END)
10453 else if(Key == VK_END)
10467 if(Shift.Contains(ssShift) && !Shift.Contains(ssAlt) && !Shift.Contains(ssCtrl) &&
NewHomeButton->Enabled &&
NewHomeButton->Visible)
10478 if(!Shift.Contains(ssCtrl))
10537 if(Key ==
'S' || Key ==
's')
10548 if(Shift.Contains(ssShift))
10564 if(Shift.Contains(ssShift) && !Shift.Contains(ssCtrl) && !Shift.Contains(ssAlt))
10611 if(Shift.Contains(ssCtrl) && !Shift.Contains(ssShift) && !Shift.Contains(ssAlt))
10616 if(Key ==
'S' || Key ==
's')
10622 if(!Shift.Contains(ssCtrl) && !Shift.Contains(ssShift) && !Shift.Contains(ssAlt))
10634 if(!Shift.Contains(ssShift) && !Shift.Contains(ssCtrl))
10641 if(!Shift.Contains(ssShift) && Shift.Contains(ssCtrl))
10646 if(Key ==
'S' || Key ==
's')
10652 if(Shift.Contains(ssShift) && !Shift.Contains(ssCtrl))
10673 if(!Shift.Contains(ssShift) && !Shift.Contains(ssCtrl))
10680 if(Shift.Contains(ssShift) && !Shift.Contains(ssCtrl))
10686 if(Key ==
'S' || Key ==
's')
10691 else if(Key ==
'H' || Key ==
'h')
10705 if(Shift.Contains(ssShift) && !Shift.Contains(ssCtrl))
10775 if(
SaveTTButton->Enabled && (Key ==
'T' || Key ==
't'))
10800 if(
FloatingInfoMenu->Enabled && !Shift.Contains(ssAlt) && Shift.Contains(ssCtrl) && Shift.Contains(ssShift))
10802 if(Key ==
'I' || Key ==
'i')
10808 if(Key ==
'S' || Key ==
's')
10812 else if(Key ==
'T' || Key ==
't')
10822 catch(
const Exception &e)
10832 if((Key != VK_SHIFT) && (Key != VK_CONTROL))
10952 catch(
const Exception &e)
10965 Application->HelpKeyword(u
"Introduction");
10967 catch(
const Exception &e)
10977 const UnicodeString Link =
"http://www.railwayoperationsimulator.com";
10978 ::ShellExecute(Handle, NULL, (Link).c_str(), NULL, NULL, SW_SHOWNORMAL);
10989 std::ofstream ColFile((
CurDir +
"\\Background.col").c_str());
11013 catch(
const Exception &e)
11027 std::ofstream ColFile((
CurDir +
"\\Background.col").c_str());
11030 ShowMessage(
"Failed to store colour file, program will default to a black background when next loaded");
11050 catch(
const Exception &e)
11064 std::ofstream ColFile((
CurDir +
"\\Background.col").c_str());
11067 ShowMessage(
"Failed to store colour file, program will default to a black background when next loaded");
11087 catch(
const Exception &e)
11143 bool ErrorFlag =
false, TooBigFlag =
false;
11164 if(!ErrorFlag && !TooBigFlag)
11174 int KPH = (MPH * 1.609344) + 0.5;
11181 int MPH = (KPH * 0.621371) + 0.5;
11192 catch(
const EConvertError &ec)
11196 catch(
const Exception &e)
11231 bool ErrorFlag =
false, TooBigFlag =
false;
11252 if(!ErrorFlag && !TooBigFlag)
11262 int KW = (HP * 0.745699872) + 0.5;
11269 int HP = (KW * 1.340482574) + 0.5;
11280 catch(
const EConvertError &ec)
11284 catch(
const Exception &e)
11297 bool ErrorFlag =
false, TooBigFlag =
false;
11318 if(!ErrorFlag && !TooBigFlag)
11328 int KPH = (MPH * 1.609344) + 0.5;
11335 int MPH = (KPH * 0.621371) + 0.5;
11346 catch(
const EConvertError &ec)
11350 catch(
const Exception &e)
11364 bool ErrorFlag =
false, TooLongFlag =
false;
11367 for(
int x = 1; x <=
MileEdit->Text.Length(); x++)
11379 for(
int x = 1; x <=
ChainEdit->Text.Length(); x++)
11391 for(
int x = 1; x <=
YardEdit->Text.Length(); x++)
11403 TooLongFlag =
true;
11406 if(!ErrorFlag && !TooLongFlag)
11408 int Miles = 0, Chains = 0, Yards = 0, Metres = 0;
11421 Metres = int((Miles * 1609.344) + (Chains * 20.1168) + (Yards * 0.9144) + 0.5);
11430 catch(
const EConvertError &ec)
11434 catch(
const Exception &e)
11465 catch(
const Exception &e)
11501 "Changes have been made to the timetable clock - you may wish to save a session before resuming operation.\n\nTo cancel all changes re-click the 'Adjust the timetable clock' button then click the reset button BEFORE resuming operation.";
11508 catch(
const Exception &e)
11526 catch(
const Exception &e)
11545 catch(
const Exception &e)
11564 catch(
const Exception &e)
11583 catch(
const Exception &e)
11602 catch(
const Exception &e)
11621 catch(
const Exception &e)
11640 catch(
const Exception &e)
11659 catch(
const Exception &e)
11677 catch(
const Exception &e)
11691 double TTClockIncrement = 1.0 / 24;
11697 catch(
const Exception &e)
11711 double TTClockIncrement = 1.0 / 144;
11717 catch(
const Exception &e)
11731 double TTClockIncrement = 1.0 / 1440;
11737 catch(
const Exception &e)
11778 catch(
const Exception &e)
11792 InfoPanel->Caption =
"PRE-START: Presetting automatic signal routes";
11803 Screen->Cursor = TCursor(-11);
11805 bool PointsChanged, AtLeastOneSet =
false;
11806 int LastIteratorValue = 0;
11813 AtLeastOneSet =
true;
11829 ShowMessage(
"No presettable automatic signal routes are available");
11831 Screen->Cursor = TCursor(-2);
11834 catch(
const Exception &e)
11848 int DispW = (
Interface->Width - 64 - 16) / 16;
11850 int DispH = (
Interface->Height - 192) / 16;
11882 catch(
const Exception &e)
11912 catch(
const Exception &e)
11938 SigImagePanel->Caption =
"Signals will be on the right hand side of the track";
11943 std::ofstream SigFile((
CurDir +
"\\Signal.hnd").c_str());
11946 ShowMessage(
"Failed to store right hand signal setting, program will default to left hand signals when next loaded");
11964 SigImagePanel->Caption =
"Signals will be on the left hand side of the track";
11969 std::ofstream SigFile((
CurDir +
"\\Signal.hnd").c_str());
11981 catch(
const Exception &e)
12000 bool TooBigFlag =
false, BadCharsFlag =
false;
12005 for(
int x = 1; x <=
MTBFEditBox->Text.Length(); x++)
12009 BadCharsFlag =
true;
12022 ShowMessage(
"Maximum value allowed is 10,000");
12031 ShowMessage(
"Value must be a whole number with no special characters");
12048 catch(
const Exception &e)
12066 "Values can only be entered or changed in Pre-Start mode\ni.e. after selecting 'Operate railway' but before clicking 'Run'");
12070 catch(
const Exception &e)
12102 catch(
const Exception &e)
12128 catch(
const Exception &e)
12144 catch(
const Exception &e)
12165 catch(
const Exception &e)
12182 catch(
const Exception &e)
12199 catch(
const Exception &e)
12215 ShowMessage(
"No boxes ticked!");
12219 Screen->Cursor = TCursor(-11);
12220 AnsiString TTTitle;
12234 ShowMessage(
"Analysis complete and file created");
12239 Screen->Cursor = TCursor(-2);
12242 catch(
const Exception &e)
12284 int WidthNum = int(
MainScreen->Width / 160) + 1;
12285 int HeightNum = int(
MainScreen->Height / 144) + 1;
12286 for(
int x = 0; x < WidthNum; x++)
12288 for(
int y = 0; y < HeightNum; y++)
12401 bool BreakFlag =
false;
12488 ZoomButton->Glyph->LoadFromResourceName(0,
"ZoomOut");
12514 InfoPanel->Caption =
"CONNECTING GAPS: Click on connecting element";
12530 UnicodeString MessageStr =
"The railway has changed, close it without saving?";
12531 int button = Application->MessageBox(MessageStr.c_str(), L
"Please confirm", MB_YESNO);
12578 std::ifstream VecFile(FileName);
12580 if(VecFile.is_open())
12600 bool GraphicsFollow =
false;
12601 int NumberOfActiveElements;
12614 if(!(EveryPrefDir->CheckOnePrefDir(0, NumberOfActiveElements, VecFile)))
12645 TDateTime First, Second;
12646 bool Finished =
false;
12648 First = TDateTime::CurrentDateTime();
12649 double TimeVal1 = 86400000 * double(First);
12653 Second = TDateTime::CurrentDateTime();
12654 double TimeVal2 = 86400000 * double(Second);
12655 if((TimeVal2 - TimeVal1) > Msec)
12705 if((LinkNumber1 == 1) || (LinkNumber1 == 3) || (LinkNumber1 == 7) || (LinkNumber1 == 9))
12713 if((LinkNumber2 == 1) || (LinkNumber2 == 3) || (LinkNumber2 == 7) || (LinkNumber2 == 9))
12864 InfoPanel->Caption =
"Select an option from the File, Mode or Help menus";
13018 InfoPanel->Caption =
"PREFERRED DIRECTION SETTING: Select preferred direction start location (right click to erase)";
13080 MTBFLabel->Caption =
"Mean time between\ntrain failures in\ntimetable hours";
13094 OperateButton->Glyph->LoadFromResourceName(0,
"RunGraphic");
13120 ShowMessage(
"Performance logfile failed to open, logs won't be saved. Ensure that there is a folder named " +
PERFLOG_DIR_NAME +
13121 " in the folder where the 'Railway.exe' program file resides");
13162 OAListBox->Items->Add(L
"to locate train");
13167 OAListBox->Items->Add(L
"Left click and");
13168 OAListBox->Items->Add(L
"hold grey area");
13169 OAListBox->Items->Add(L
"to move panel");
13199 OperateButton->Glyph->LoadFromResourceName(0,
"RunGraphic");
13221 OAListBox->Items->Add(L
"to locate train");
13226 OAListBox->Items->Add(L
"Left click and");
13227 OAListBox->Items->Add(L
"hold grey area");
13228 OAListBox->Items->Add(L
"to move panel");
13242 MTBFLabel->Caption =
"Mean time between\ntrain failures in\ntimetable hours";
13251 MTBFLabel->Caption =
"Mean time between\ntrain failures in\ntimetable hours";
13288 InfoPanel->Caption =
"ADDING TRACK: Select element then left click to add it. Right click an element to remove it.";
13308 InfoPanel->Caption =
"ADDING GRAPHIC: Left click layout to add SELECTED graphic, right click to remove ANY graphic.";
13313 InfoPanel->Caption =
"SELECTING USER GRAPHIC: Select the graphic file then add as many as necessary to the layout.";
13317 int HLoc, VLoc, Count;
13319 if(div(Count, 2).rem == 1)
13321 ShowMessage(
"Can't connect, there are an odd number of gaps");
13336 ShowMessage(
"Error - Even number of gaps but all set after first call to HighLightOneGap");
13346 InfoPanel->Caption =
"CONNECTING GAPS: Click on connecting gap";
13353 InfoPanel->Caption =
"ADDING/EDITING TEXT: Left click to add, right click first letter to erase, or left click first letter to edit)";
13368 InfoPanel->Caption =
"MOVING TEXT OR GRAPHIC: If text left click first letter, if graphic left click anywhere, then drag";
13375 InfoPanel->Caption =
"NAMING LOCATIONS: Click on location element to add or change name";
13383 InfoPanel->Caption =
"DISTANCE/SPEED SETTING: Select first location (only non-default elements marked)";
13394 InfoPanel->Caption =
"DISTANCE/SPEED SETTING: Select next location";
13396 InfoPanel->Caption =
"DISTANCE/SPEED SETTING: Continue or set values (overall length), or right click to cancel/truncate";
13408 InfoPanel->Caption =
"SELECTING: Select area - click left mouse && drag";
13418 InfoPanel->Caption =
"COPYING: Left click in selection && drag";
13442 bool EraseSuccessfulFlag, NeedToLink =
false, TextChangesMade =
false, GraphicChangesMade =
false; ;
13443 int ErasedTrackVectorPosition;
13444 Screen->Cursor = TCursor(-11);
13446 InfoPanel->Caption =
"CUT PROCESSING: Please do not click the mouse";
13453 if(EraseSuccessfulFlag)
13455 if(ErasedTrackVectorPosition > -1)
13465 int HighSelectVPos =
SelectRect.bottom * 16;
13471 if((TextPtr->HPos >= LowSelectHPos) && (TextPtr->HPos < HighSelectHPos) && (TextPtr->VPos >= LowSelectVPos) && (TextPtr->VPos <
13477 TextChangesMade =
true;
13487 if((GraphicPtr->HPos >= LowSelectHPos) && ((GraphicPtr->HPos + GraphicPtr->Width) < HighSelectHPos) && (GraphicPtr->VPos >= LowSelectVPos)
13488 && ((GraphicPtr->VPos + GraphicPtr->Height) < HighSelectVPos))
13491 GraphicChangesMade =
true;
13498 Screen->Cursor = TCursor(-2);
13503 InfoPanel->Caption =
"CUTTING: Left click in selection && drag";
13519 if(NeedToLink || TextChangesMade || GraphicChangesMade)
13534 bool NeedToLink =
false;
13535 bool TrackLinkingRequiredFlag;
13536 Screen->Cursor = TCursor(-11);
13538 InfoPanel->Caption =
"PASTING: Please wait";
13545 bool TrackEraseSuccessfulFlag;
13546 int ErasedTrackVectorPosition;
13548 for(
int x = LowSelectHLoc; x < HighSelectHLoc; x++)
13550 for(
int y = LowSelectVLoc; y < HighSelectVLoc; y++)
13553 if(ErasedTrackVectorPosition > -1)
13568 if((TextPtr->HPos >= LowSelectHPos) && (TextPtr->HPos < HighSelectHPos) && (TextPtr->VPos >= LowSelectVPos) && (TextPtr->VPos <
13583 if((GraphicPtr->HPos >= LowSelectHPos) && ((GraphicPtr->HPos + GraphicPtr->Width) < HighSelectHPos) && (GraphicPtr->VPos >= LowSelectVPos)
13584 && ((GraphicPtr->VPos + GraphicPtr->Height) < HighSelectVPos))
13605 bool InternalChecks =
false;
13609 TrackLinkingRequiredFlag, InternalChecks);
13625 if(TrackLinkingRequiredFlag)
13633 TextPtr->HPos += HDiff * 16;
13634 TextPtr->VPos += VDiff * 16;
13635 AnsiString TempString = TextPtr->TextString;
13651 if(TextPtr->TextString.SubString(1, 4) ==
"##**")
13653 TempString = TextPtr->TextString.SubString(5, TextPtr->TextString.Length());
13656 TextPtr->TextString =
"";
13668 for(TTrack::TUserGraphicVector::iterator GraphicPtr =
Track->
SelectGraphicVector.begin(); GraphicPtr < Track->SelectGraphicVector.end();
13671 GraphicPtr->HPos += HDiff * 16;
13672 GraphicPtr->VPos += VDiff * 16;
13685 Screen->Cursor = TCursor(-2);
13699 UnicodeString MessageStr =
"Selected area will be deleted - proceed?";
13700 int button = Application->MessageBox(MessageStr.c_str(), L
"Please confirm", MB_YESNO);
13705 bool EraseSuccessfulFlag, NeedToLink =
false, TextChangesMade =
false, GraphicChangesMade =
false;
13706 int ErasedTrackVectorPosition;
13707 Screen->Cursor = TCursor(-11);
13709 InfoPanel->Caption =
"DELETING: Please wait";
13716 if(EraseSuccessfulFlag)
13718 if(ErasedTrackVectorPosition > -1)
13728 int HighSelectVPos =
SelectRect.bottom * 16;
13734 AnsiString Check = TextPtr->TextString;
13735 if((TextPtr->HPos >= LowSelectHPos) && (TextPtr->HPos < HighSelectHPos) && (TextPtr->VPos >= LowSelectVPos) && (TextPtr->VPos <
13741 TextChangesMade =
true;
13760 if((GraphicPtr->HPos >= LowSelectHPos) && ((GraphicPtr->HPos + GraphicPtr->Width) < HighSelectHPos) && (GraphicPtr->VPos >= LowSelectVPos)
13761 && ((GraphicPtr->VPos + GraphicPtr->Height) < HighSelectVPos))
13766 if((UserGraphicPtr->HPos == GraphicPtr->HPos) && (UserGraphicPtr->VPos == GraphicPtr->VPos) &&
13767 (UserGraphicPtr->Width == GraphicPtr->Width) && (UserGraphicPtr->Height == GraphicPtr->Height) &&
13768 (UserGraphicPtr->FileName == GraphicPtr->FileName))
13771 GraphicChangesMade =
true;
13788 if(NeedToLink || TextChangesMade || GraphicChangesMade)
13792 Screen->Cursor = TCursor(-2);
13844 bool LeadingPointsAtLastElement =
false;
13847 if(LeadingPointsAtLastElement)
13849 InfoPanel->Caption =
"PREFERRED DIRECTION SETTING: Can't end on leading points, select next location or truncate";
13854 InfoPanel->Caption =
"PREFERRED DIRECTION SETTING: Select next preferred direction location (right click to truncate)";
13859 InfoPanel->Caption =
"PREFERRED DIRECTION SETTING: Add selection or select next location (right click to truncate)";
13874 InfoPanel->Caption =
"SELECTING: Select area - click left mouse && drag";
13914 OperateButton->Glyph->LoadFromResourceName(0,
"PauseGraphic");
13957 Display->
PerformanceLog(15, TimeMessage +
"Timetable clock speed changed to one sixteenth normal");
13962 if(TTClockTimeChange > 0.000347)
13965 int MinsIncrease = ((TTClockTimeChange * 1440) + 0.5);
13966 int HoursIncrease = 0;
13967 while(MinsIncrease >= 60)
13970 MinsIncrease -= 60;
13972 if(HoursIncrease == 0)
13973 TimeMessage +=
"Timetable clock incremented by " + AnsiString(MinsIncrease) +
"m";
13974 else if(MinsIncrease == 0)
13975 TimeMessage +=
"Timetable clock incremented by " + AnsiString(HoursIncrease) +
"h";
13977 TimeMessage +=
"Timetable clock incremented by " + AnsiString(HoursIncrease) +
"h " + AnsiString(MinsIncrease) +
"m";
13988 MTBFLabel->Caption =
"Mean time between\ntrain failures in\ntimetable hours";
13996 MTBFLabel->Caption =
"Mean time between\ntrain failures in\ntimetable hours";
14005 OperateButton->Glyph->LoadFromResourceName(0,
"RunGraphic");
14033 float LockDelay = 120.0;
14039 bool BreakFlag =
false;
14043 if((TTClockTime - LRVIT->LockStartTime) > TDateTime(LockDelay / 86400))
14046 AnsiString(LRVIT->LastTrackVectorPosition));
14047 while(Route.
LastElementPtr(9)->GetTrackVectorPosition() != LRVIT->TruncateTrackVectorPosition)
14060 if(Route.
LastElementPtr(17)->GetTrackVectorPosition() == LRVIT->TruncateTrackVectorPosition)
14099 int TempLockedVectorNumber;
14109 if(((TTClockTime - AutoSigVectorIT->PassoutTime) > TDateTime(AutoSigVectorIT->FirstDelay / 86400)) && (AutoSigVectorIT->AccessNumber == 0))
14112 AutoSigVectorIT->AccessNumber++;
14115 if(((TTClockTime - AutoSigVectorIT->PassoutTime) > TDateTime(AutoSigVectorIT->SecondDelay / 86400)) && (AutoSigVectorIT->AccessNumber == 1))
14118 AutoSigVectorIT->AccessNumber++;
14121 if(((TTClockTime - AutoSigVectorIT->PassoutTime) > TDateTime(AutoSigVectorIT->ThirdDelay / 86400)) && (AutoSigVectorIT->AccessNumber == 2))
14124 AutoSigVectorIT->AccessNumber++;
14132 if(AutoSigVectorIT->AccessNumber > 2)
14147 TPoint MousePoint = Mouse->CursorPos;
14148 int ScreenX = MousePoint.x -
MainScreen->ClientOrigin.x;
14149 int ScreenY = MousePoint.y -
MainScreen->ClientOrigin.y;
14151 if((ScreenX > (
MainScreen->Width - 1)) || (ScreenY > (
MainScreen->Height - 1)) || (ScreenX < 0) || (ScreenY < 0))
14161 ((MousePoint.y - ClientOrigin.y) >=
PerformancePanel->Top) && ((MousePoint.y - ClientOrigin.y) <=
14173 ((MousePoint.y - ClientOrigin.y) >=
OperatorActionPanel->Top) && ((MousePoint.y - ClientOrigin.y) <=
14182 AnsiString TrackFloat =
"", TrainStatusFloat =
"", TrainTTFloat =
"";
14184 bool ShowTrackFloatFlag =
false, ShowTrainStatusFloatFlag =
false, ShowTrainTTFloatFlag =
false;
14196 bool ActiveTrackFoundFlag =
false, InactiveTrackFoundFlag =
false, TwoTrack =
false;
14197 AnsiString Length01Str =
"", Length23Str =
"", SpeedLimit01Str =
"", SpeedLimit23Str =
"";
14198 AnsiString StationEntryStopLinkPos1Str =
"", StationEntryStopLinkPos2Str =
"";
14199 AnsiString ATrackSN =
"", ATrackTN =
"", IATrackSN =
"", LengthAndSpeedCaption =
"";
14200 AnsiString SigAspectString =
"";
14204 if(InactiveTrackFoundFlag)
14209 if(ActiveTrackFoundFlag)
14216 if((ATrackTN !=
"") && (!InactiveTrackFoundFlag || ((InactiveTrackElement.
TrackType !=
Platform) &&
14220 ShowMessage(
"Error - Track has timetable name without corresponding plat/named loc");
14225 ShowMessage(
"Error - plat/named loc and track have different names, or plat/named loc named but not track");
14231 Length01Str = AnsiString(ActiveTrackElement.
Length01);
14232 if(Length01Str ==
"-1")
14233 Length01Str =
"Not Set";
14234 SpeedLimit01Str = AnsiString(ActiveTrackElement.
SpeedLimit01);
14235 if(SpeedLimit01Str ==
"-1")
14236 SpeedLimit01Str =
"Not Set";
14239 Length23Str = AnsiString(ActiveTrackElement.
Length23);
14240 if(Length23Str ==
"-1")
14241 Length23Str =
"Not Set";
14242 SpeedLimit23Str = AnsiString(ActiveTrackElement.
SpeedLimit23);
14243 if(SpeedLimit23Str ==
"-1")
14244 SpeedLimit23Str =
"Not Set";
14247 LengthAndSpeedCaption =
"Straight track length = " + Length01Str +
" m" +
'\n' +
"Diverging track length = " + Length23Str +
" m" +
'\n' +
14248 "Straight track speed limit = " + SpeedLimit01Str +
" km/h" +
'\n' +
"Diverging track speed limit = " + SpeedLimit23Str +
" km/h";
14252 LengthAndSpeedCaption =
"Left diverging track length = " + Length01Str +
" m" +
'\n' +
"Right diverging track length = " + Length23Str +
14253 " m" +
'\n' +
"Left diverging track speed limit = " + SpeedLimit01Str +
" km/h" +
'\n' +
"Right diverging track Speed Limit = " +
14254 SpeedLimit23Str +
" km/h";
14259 if((ActiveTrackElement.
SpeedTag == 15) || (ActiveTrackElement.
SpeedTag == 46))
14261 LengthAndSpeedCaption =
"Horizontal track length = " + Length01Str +
" m" +
'\n' +
"Other track length = " + Length23Str +
" m" +
'\n' +
14262 "Horizontal track speed limit = " + SpeedLimit01Str +
" km/h" +
'\n' +
"Other track speed limit = " + SpeedLimit23Str +
" km/h";
14264 else if(ActiveTrackElement.
SpeedTag == 47)
14266 LengthAndSpeedCaption =
"Horizontal track length = " + Length23Str +
" m" +
'\n' +
"Other track length = " + Length01Str +
" m" +
'\n' +
14267 "Horizontal track speed limit = " + SpeedLimit23Str +
" km/h" +
'\n' +
"Other track speed limit = " + SpeedLimit01Str +
" km/h";
14269 else if(ActiveTrackElement.
SpeedTag == 45)
14271 LengthAndSpeedCaption =
"Vertical track length = " + Length01Str +
" m" +
'\n' +
"Other track length = " + Length23Str +
" m" +
'\n' +
14272 "Vertical track speed limit = " + SpeedLimit01Str +
" km/h" +
'\n' +
"Other track speed limit = " + SpeedLimit23Str +
" km/h";
14274 else if(ActiveTrackElement.
SpeedTag == 44)
14276 LengthAndSpeedCaption =
"Vertical track length = " + Length23Str +
" m" +
'\n' +
"Other track length = " + Length01Str +
" m" +
'\n' +
14277 "Vertical track speed limit = " + SpeedLimit23Str +
" km/h" +
'\n' +
"Other track speed limit = " + SpeedLimit01Str +
" km/h";
14279 else if(ActiveTrackElement.
SpeedTag == 16)
14281 LengthAndSpeedCaption =
"Top left to bottom right track length = " + Length01Str +
" m" +
'\n' +
"Other track length = " + Length23Str +
14282 " m" +
'\n' +
"Top left to bottom right track speed limit = " + SpeedLimit01Str +
" km/h" +
'\n' +
"Other track speed limit = " +
14283 SpeedLimit23Str +
" km/h";
14288 LengthAndSpeedCaption =
"Top track length = " + Length01Str +
" m" +
'\n' +
"Bottom track length = " + Length23Str +
" m" +
'\n' +
14289 "Top track speed limit = " + SpeedLimit01Str +
" km/h" +
'\n' +
"Bottom track speed limit = " + SpeedLimit23Str +
" km/h";
14294 LengthAndSpeedCaption =
"Track length = " + Length01Str +
" m" +
'\n' +
"Track speed limit = " + SpeedLimit01Str +
" km/h";
14297 if(ActiveTrackFoundFlag)
14301 ShowTrackFloatFlag =
true;
14304 TrackFloat =
"Location = " + ATrackTN +
'\n' + LengthAndSpeedCaption +
'\n' +
"ID = " + AnsiString(ActiveTrackElement.
ElementID);
14306 else if(ATrackSN !=
"")
14308 TrackFloat =
"Location = " + ATrackSN +
'\n' + LengthAndSpeedCaption +
'\n' +
"ID = " + AnsiString(ActiveTrackElement.
ElementID);
14311 else if(InactiveTrackFoundFlag)
14313 TrackFloat =
"Location unnamed\n" + LengthAndSpeedCaption +
'\n' +
"ID = " + AnsiString(ActiveTrackElement.
ElementID);
14318 TrackFloat = LengthAndSpeedCaption +
'\n' +
"Track Element ID = " + AnsiString(ActiveTrackElement.
ElementID);
14324 SigAspectString =
"\nThree-aspect signal";
14328 SigAspectString =
"\nTwo-aspect signal";
14332 SigAspectString =
"\nGround signal";
14336 SigAspectString =
"\nFour-aspect signal";
14338 TrackFloat += SigAspectString;
14341 else if(InactiveTrackFoundFlag)
14344 ShowTrackFloatFlag =
true;
14347 if(IATrackSN ==
"")
14349 TrackFloat =
"Location unnamed\nID = " + AnsiString(InactiveTrackElement.
ElementID);
14353 TrackFloat =
"Location = " + IATrackSN +
'\n' +
"ID = " + AnsiString(InactiveTrackElement.
ElementID);
14358 TrackFloat =
"ID = " + AnsiString(InactiveTrackElement.
ElementID);
14368 AnsiString FormatOneDPStr =
"####0.0";
14369 AnsiString FormatNoDPStr =
"#######0";
14371 AnsiString MaxBrakeStr =
"";
14372 AnsiString SpecialStr =
"", MaxSpeedStr =
"";
14382 ShowTrainStatusFloatFlag =
true;
14383 AnsiString HeadCode =
"", ServiceReferenceInfo =
"", Status =
"", CurrSpeedStr =
"", BrakePCStr =
"", NextStopStr =
"", TimeLeftStr =
"",
14384 TimeToNextMovementStr =
"", MassStr =
"", PowerStr =
"";
14386 MassStr = AnsiString::FormatFloat(FormatNoDPStr, ((
double)Train.
Mass) / 1000);
14387 PowerStr = AnsiString::FormatFloat(FormatNoDPStr, Train.
PowerAtRail / 1000 / 0.8);
14389 MaxSpeedStr =
"30";
14391 MaxSpeedStr = AnsiString::FormatFloat(FormatNoDPStr, Train.
MaxRunningSpeed);
14395 TDateTime TimeLeft;
14397 MaxBrakeStr = AnsiString::FormatFloat(FormatNoDPStr, (Train.
MaxBrakeRate * Train.
Mass / 9810));
14406 ServiceReferenceInfo =
"\nFirst service";
14409 ServiceReferenceInfo =
"\nRepeat service no. " + AnsiString(Train.
RepeatNumber);
14411 ServiceReferenceInfo =
"\nRepeat service no. " + AnsiString(Train.
RepeatNumber) +
" of ref. " +
14422 Status =
"Stopped on signaller's instruction";
14424 Status =
"Not in service";
14426 Status =
"Stopped at buffers";
14428 Status =
"Stopped at signal";
14430 Status =
"Stopped - forward track occupied";
14438 Status =
"Stopped without power - train failed";
14440 Status =
"Stopped without power";
14443 Status =
"Stopped - signal passed at danger";
14445 Status =
"Derailed";
14447 Status =
"Crashed";
14454 Status =
"Accelerating";
14461 if(BrakePCRate < 55)
14462 Status =
"Light braking";
14463 else if(BrakePCRate < 90)
14464 Status =
"Heavy braking";
14466 Status =
"Emergency braking";
14472 if(BrakePCRate < 55)
14473 Status =
"Light braking";
14474 else if(BrakePCRate < 90)
14475 Status =
"Heavy braking";
14477 Status =
"Emergency braking";
14483 Status =
"Accelerating";
14489 Status =
"Accelerating";
14491 ((Train.
ExitSpeedFull - Train.
ExitSpeedHalf) * (
double(ElapsedDeltaT - FirstHalfTimeDeltaT) / double(SecondHalfTimeDeltaT)));
14500 Status =
"Coasting - train failed";
14504 Status =
"Coasting - no power";
14510 Status =
"Constant speed";
14521 Status =
"Coasting - train failed";
14525 Status =
"Coasting - no power";
14531 Status =
"Constant speed";
14538 NextStopStr =
"At signaller's discretion";
14540 NextStopStr =
"None";
14546 SpecialStr =
"Train under signaller control" + AnsiString(
'\n');
14550 SpecialStr =
"Restricted speed - being called on" + AnsiString(
'\n');
14554 if(RemTimeHalf < 0)
14557 if(RemTimeFull < 0)
14559 if(RemTimeHalf > 0)
14560 TimeLeft = RemTimeHalf;
14562 TimeLeft = RemTimeFull;
14563 TimeToNextMovementStr =
"Time to next movement (sec) = " + TimeLeftStr.FormatFloat(FormatOneDPStr, TimeLeft);
14565 TimeToNextMovementStr =
"";
14569 MaxSpeedStr +
"km/h; Power " + PowerStr +
"kW" +
'\n' +
"Mass " + MassStr +
"Te; Brakes " + MaxBrakeStr +
"Te" +
'\n' + SpecialStr +
14570 Status +
'\n' +
"Next: " + NextStopStr;
14575 MaxSpeedStr +
"km/h; Power " + PowerStr +
"kW" +
'\n' +
"Mass " + MassStr +
"Te; Brakes " + MaxBrakeStr +
"Te" +
'\n' + SpecialStr +
14576 Status +
": " + CurrSpeedStr.FormatFloat(FormatNoDPStr, CurrSpeed) +
"km/h" +
'\n' +
"Next: " + NextStopStr;
14581 ShowTrainTTFloatFlag =
true;
14590 TrainStatusFloat =
"No trains expected";
14591 TrainTTFloat =
"No timetable";
14595 ShowTrainStatusFloatFlag =
true;
14597 ShowTrainTTFloatFlag =
true;
14604 (CTEIt->second.TrainDataEntryPtr->TrainOperatingDataVector.at(CTEIt->second.RepeatNumber).RunningEntry !=
NotStarted)))
14611 AnsiString ServiceReferenceInfo =
"";
14615 if(CTEIt->second.RepeatNumber == 0)
14618 ServiceReferenceInfo =
"\nFirst service of ref. " + TTDEPtr->
ServiceReference;
14620 ServiceReferenceInfo =
"\nFirst service";
14623 ServiceReferenceInfo =
"\nRepeat service no. " + AnsiString(CTEIt->second.RepeatNumber);
14625 ServiceReferenceInfo =
"\nRepeat service no. " + AnsiString(CTEIt->second.RepeatNumber) +
" of ref. " +
14631 ServiceReferenceInfo =
"\nService reference " + TTDEPtr->
ServiceReference;
14635 SpecialStr =
"\nTrain under signaller control";
14637 if(EntrySpeed > LineSpeedLimit)
14638 EntrySpeed = LineSpeedLimit;
14643 if(EntrySpeed > LineSpeedLimit)
14644 EntrySpeed = LineSpeedLimit;
14648 TDateTime TempTime = CTEIt->first;
14650 TrainStatusFloat = CTEIt->second.HeadCode +
": " + CTEIt->second.Description + ServiceReferenceInfo +
"\nEntry speed " +
14651 AnsiString::FormatFloat(FormatNoDPStr, EntrySpeed) +
"km/h" + SpecialStr +
"\nDelayed, was due at " +
14656 TDateTime TempTime = CTEIt->first;
14658 TrainStatusFloat = CTEIt->second.HeadCode +
": " + CTEIt->second.Description + ServiceReferenceInfo +
"\nEntry speed " +
14659 AnsiString::FormatFloat(FormatNoDPStr, EntrySpeed) +
"km/h" + SpecialStr +
"\nExpected at " +
14667 CTEIt->second.IncrementalMinutes, CTEIt->second.IncrementalDigits);
14678 AnsiString Caption;
14680 if(!ShowTrackFloatFlag && !ShowTrainStatusFloatFlag && !ShowTrainTTFloatFlag)
14686 else if(ShowTrackFloatFlag && !ShowTrainStatusFloatFlag && !ShowTrainTTFloatFlag)
14688 Caption = TrackFloat;
14690 else if(!ShowTrackFloatFlag && ShowTrainStatusFloatFlag && !ShowTrainTTFloatFlag)
14692 Caption = TrainStatusFloat;
14694 else if(ShowTrackFloatFlag && ShowTrainStatusFloatFlag && !ShowTrainTTFloatFlag)
14696 Caption = TrainStatusFloat +
'\n' +
'\n' + TrackFloat;
14698 else if(!ShowTrackFloatFlag && !ShowTrainStatusFloatFlag && ShowTrainTTFloatFlag)
14700 if(TrainStatusFloat ==
"No trains expected")
14701 Caption = TrainStatusFloat;
14703 Caption = TrainTTFloat;
14705 else if(ShowTrackFloatFlag && !ShowTrainStatusFloatFlag && ShowTrainTTFloatFlag)
14707 if(TrainStatusFloat ==
"No trains expected")
14708 Caption = TrainStatusFloat +
'\n' +
'\n' + TrackFloat;
14710 Caption = TrainTTFloat +
'\n' +
'\n' + TrackFloat;
14712 else if(!ShowTrackFloatFlag && ShowTrainStatusFloatFlag && ShowTrainTTFloatFlag)
14714 if(TrainStatusFloat ==
"No trains expected")
14715 Caption = TrainStatusFloat;
14717 Caption = TrainStatusFloat +
'\n' +
'\n' + TrainTTFloat;
14719 else if(ShowTrackFloatFlag && ShowTrainStatusFloatFlag && ShowTrainTTFloatFlag)
14721 if(TrainStatusFloat ==
"No trains expected")
14722 Caption = TrainStatusFloat +
'\n' +
'\n' + TrackFloat;
14724 Caption = TrainStatusFloat +
'\n' +
'\n' + TrainTTFloat +
'\n' +
'\n' + TrackFloat;
14822 InfoPanel->Caption =
"PRE-START: Route setting in progress";
14824 InfoPanel->Caption =
"OPERATING: Route setting in progress";
14987 throw Exception(
"Failed to find a route at LC position HLoc = " + (AnsiString)H +
" VLoc = " + (AnsiString)V);
14992 if(RouteNumber > -1)
15026 bool SaveRailwayButtonsFlag =
true;
15035 SaveRailwayButtonsFlag =
false;
15052 SaveRailwayButtonsFlag =
false;
15060 SaveRailwayButtonsFlag =
false;
15113 bool ZoomFlag =
true, HomeFlag =
true, NewHomeFlag =
true, ScreenLeftFlag =
true, ScreenRightFlag =
true, ScreenUpFlag =
true, ScreenDownFlag =
true,
15114 TrackBuildPanelEnabledFlag =
true, PrefDirPanelEnabledFlag =
true, OperatingPanelEnabledFlag =
true, TimetablePanelEnabledFlag =
true;
15116 AnsiString TrackBuildPanelLabelCaptionStr =
"Build/modify";
15117 AnsiString PrefDirPanelLabelCaptionStr =
"Preferred direction selection";
15118 AnsiString OperatingPanelLabelCaptionStr =
"Operation";
15119 AnsiString TimetablePanelLabelCaptionStr =
"Timetable editor";
15124 ScreenLeftFlag =
false;
15126 ScreenRightFlag =
false;
15128 ScreenUpFlag =
false;
15130 ScreenDownFlag =
false;
15135 ScreenLeftFlag =
false;
15137 ScreenRightFlag =
false;
15139 ScreenUpFlag =
false;
15141 ScreenDownFlag =
false;
15147 NewHomeFlag =
false;
15148 ScreenLeftFlag =
false;
15149 ScreenRightFlag =
false;
15150 ScreenUpFlag =
false;
15151 ScreenDownFlag =
false;
15157 TrackBuildPanelEnabledFlag =
false;
15158 TrackBuildPanelLabelCaptionStr =
"Disabled";
15159 PrefDirPanelEnabledFlag =
false;
15160 PrefDirPanelLabelCaptionStr =
"Disabled";
15161 OperatingPanelEnabledFlag =
false;
15162 OperatingPanelLabelCaptionStr =
"Disabled";
15163 TimetablePanelEnabledFlag =
false;
15164 TimetablePanelLabelCaptionStr =
"Disabled";
15172 OperatingPanelEnabledFlag =
false;
15173 OperatingPanelLabelCaptionStr =
"Disabled";
15176 NewHomeFlag =
false;
15177 ScreenLeftFlag =
false;
15178 ScreenRightFlag =
false;
15179 ScreenUpFlag =
false;
15180 ScreenDownFlag =
false;
15194 NewHomeFlag =
false;
15195 ScreenLeftFlag =
false;
15196 ScreenRightFlag =
false;
15197 ScreenUpFlag =
false;
15198 ScreenDownFlag =
false;
15205 NewHomeFlag =
false;
15206 ScreenLeftFlag =
false;
15207 ScreenRightFlag =
false;
15208 ScreenUpFlag =
false;
15209 ScreenDownFlag =
false;
15217 NewHomeFlag =
false;
15218 ScreenLeftFlag =
false;
15219 ScreenRightFlag =
false;
15220 ScreenUpFlag =
false;
15221 ScreenDownFlag =
false;
15246 if(ScreenRightFlag)
15258 if(OperatingPanelEnabledFlag)
15262 if(TrackBuildPanelEnabledFlag)
15266 if(PrefDirPanelEnabledFlag)
15270 if(TimetablePanelEnabledFlag)
15289 bool CallOnValid =
false;
15295 CallOnValid =
true;
15387 Screen->Cursor = TCursor(-2);
15430 Caption =
"Railway: New railway under development";
15432 Caption =
"Railway: " +
RailwayTitle +
" under development";
15521 TFont *TempFont =
new TFont;
15523 TempFont->Style.Clear();
15524 TempFont->Name =
"MS Sans Serif";
15525 TempFont->Size = 10;
15527 TempFont->Charset = (TFontCharset)(0);
15633 if(NonPrefDirChangesMade)
15657 AnsiString CurrentDateTimeStr =
"", TimetableTimeStr =
"", SessionFileStr =
"";
15658 Screen->Cursor = TCursor(-11);
15659 CurrentDateTimeStr = TDateTime::CurrentDateTime().FormatString(
"dd-mm-yyyy hh.nn.ss");
15662 TimetableTimeStr = TimetableTimeStr.SubString(1, 2) +
'.' + TimetableTimeStr.SubString(4, 2) +
'.' + TimetableTimeStr.SubString(7, 2);
15665 std::ofstream SessionFile(SessionFileStr.c_str());
15666 if(!(SessionFile.fail()))
15708 SessionFile.close();
15709 DeleteFile(SessionFileStr);
15710 Screen->Cursor = TCursor(-2);
15742 SessionFile.close();
15750 " in the folder where the 'Railway.exe' program file resides");
15752 Screen->Cursor = TCursor(-2);
15755 catch(
const Exception &e)
15784 Screen->Cursor = TCursor(-11);
15789 if(!(SessionFile.fail()))
15796 int LastCharBeforeFloat = TempString.LastDelimiter(
'*');
15797 if((LastCharBeforeFloat == 0) || (LastCharBeforeFloat == TempString.Length()))
15804 AnsiString FloatStr = TempString.SubString(LastCharBeforeFloat + 1, TempString.Length() - LastCharBeforeFloat);
15820 bool GraphicsFollow =
false;
15836 SessionFile.close();
15837 Screen->Cursor = TCursor(-2);
15838 ShowMessage(
"Corruption in preferred direction section of the session file, session can't be loaded");
15846 SessionFile.close();
15847 Screen->Cursor = TCursor(-2);
15848 ShowMessage(
"Corruption in route section of the session file, session can't be loaded");
15860 if(TempString ==
"***BarriersDownVector***")
15868 SessionFile.close();
15869 Screen->Cursor = TCursor(-2);
15870 ShowMessage(
"Unable to load timetable section of the session file, session can't be loaded");
15877 SessionFile.close();
15878 Screen->Cursor = TCursor(-2);
15879 throw Exception(
"TimetableTitle null in LoadSession");
15897 ShowMessage(
"Performance logfile failed to open, logs won't be saved. Ensure that there is a folder named " +
PERFLOG_DIR_NAME +
15898 " in the folder where the 'Railway.exe' program file resides");
15904 SessionFile.get(TempChar);
15905 while(!SessionFile.eof() && ((TempChar ==
'\n') || (TempChar ==
'\0')))
15907 SessionFile.get(TempChar);
15909 if(SessionFile.eof())
15913 SessionFile.close();
15924 double PowerDouble;
15932 SessionFile.close();
15968 ShowMessage(
"Session file integrity check failed, unable to load session.");
15970 Screen->Cursor = TCursor(-2);
15974 catch(
const Exception &e)
15976 if((e.Message.Pos(
"esource") > 0) || (e.Message.Pos(
"arameter") > 0))
15978 Screen->Cursor = TCursor(-2);
15989 UnicodeString MessageStr =
15990 "Insufficient memory available to load the file, and partial load likely to be corrupt. Application will terminate. Try loading the session as the first action after reloading the program.";
15992 Application->MessageBox(MessageStr.c_str(), L
"Out of memory", MB_OK | MB_ICONERROR);
15993 Application->Terminate();
16064 if(OpMode ==
"PreStart")
16122 AnsiString OpMode =
"";
16129 else if((OpMode !=
"PreStart") && (OpMode !=
"NotPreStart"))
16361 SessionFile.close();
16362 SessionFile.open(SessionFileStr.c_str(), std::ios_base::app | std::ios_base::binary);
16376 ShowMessage(
"Failed to open temporary timetable file. Unable to save the session");
16382 char *Buffer =
new char[10000];
16387 BytesRead = FileRead(Handle, Buffer, 10000);
16388 SessionFile.write(Buffer, BytesRead);
16389 if(BytesRead < 10000)
16395 SessionFile.close();
16396 SessionFile.open(SessionFileStr.c_str(), std::ios_base::app | std::ios_base::out);
16420 if(!FileExists(TimetableFileName))
16427 ErrorFile.open(ErrorFileStr.c_str(), std::ios_base::app | std::ios_base::binary);
16429 int Handle = FileOpen(TimetableFileName, fmOpenRead);
16436 Handle = FileOpen(TimetableFileName, fmOpenRead);
16446 char *Buffer =
new char[10000];
16451 BytesRead = FileRead(Handle, Buffer, 10000);
16452 ErrorFile.write(Buffer, BytesRead);
16453 if(BytesRead < 10000)
16460 ErrorFile.open(ErrorFileStr.c_str(), std::ios_base::app | std::ios_base::out);
16488 int TempTTFileNumber = 0;
16490 while(FileExists(
CurDir +
"\\TmpTT" + AnsiString(TempTTFileNumber) +
".tmp"))
16492 TempTTFileNumber++;
16500 if(!TTBFile.fail())
16502 char *Buffer =
new char[10000];
16503 char TempChar = (char)(SessionFile.peek());
16504 if(TempChar ==
'\n')
16505 SessionFile.get(TempChar);
16506 if(!SessionFile.getline(Buffer, 10000,
'\0'))
16515 for(
int x = 0; x < 10000; x++)
16517 if(Buffer[x] !=
'\0')
16522 while(AnsiString(Buffer) !=
"***End***")
16524 TTBFile.write(Buffer, Count);
16525 TTBFile.write(&Zero, 1);
16527 if(!SessionFile.getline(Buffer, 10000,
'\0'))
16536 for(
int x = 0; x < 10000; x++)
16538 if(Buffer[x] !=
'\0')
16548 bool GiveMessagesFalse =
false;
16549 bool CheckLocationsExistInRailwayTrue =
true;
16552 std::ifstream TTBLFile(
TempTTFileName.c_str(), std::ios_base::binary);
16553 if(TTBLFile.is_open())
16555 bool SessionFileTrue =
true;
16586 for(
int x = 0; x < NumberOfTrainEntries; x++)
16594 for(
int y = 0; y < NumberOfTrains; y++)
16619 AnsiString OutString;
16626 while(OutString !=
"***End***")
16635 if(SessionFile.fail())
16640 int NumberOfTrainEntries;
16647 for(
int x = 0; x < NumberOfTrainEntries; x++)
16649 int NumberOfTrains;
16655 for(
int y = 0; y < NumberOfTrains; y++)
16684 bool EndOfFile =
false;
16686 char *TrainTimetableString =
new char[10000];
16690 TTBLFile.getline(TrainTimetableString, 10000,
'\0');
16691 if(TTBLFile.eof() && (TrainTimetableString[0] ==
'\0'))
16697 AnsiString OneLine(TrainTimetableString);
16698 bool FinalCallTrue =
true;
16700 CheckLocationsExistInRailway))
16702 TTBLFile.getline(TrainTimetableString, 10000,
'\0');
16703 if(TTBLFile.eof() && (TrainTimetableString[0] ==
'\0'))
16706 throw Exception(
"Timetable FinalCall error - no start time on own line, Count = 0");
16708 OneLine = AnsiString(TrainTimetableString);
16714 TTBLFile.getline(TrainTimetableString, 10000,
'\0');
16715 if(TTBLFile.eof() && (TrainTimetableString[0] ==
'\0'))
16721 OneLine = AnsiString(TrainTimetableString);
16726 throw Exception(
"Timetable FinalCall error in processing one timetable line, Count = " + AnsiString(Count));
16728 if(EndOfFile && (Count < 2))
16731 throw Exception(
"Timetable FinalCall error - too few or no relevant entries, Count = " + AnsiString(Count));
16736 delete TrainTimetableString;
16743 ShowMessage(
"Timetable secondary integrity check failed - unable to load");
16779 bool EndOfFile =
false;
16781 char *TrainTimetableString =
new char[10000];
16785 TTBLFile.getline(TrainTimetableString, 10000,
'\0');
16786 if(TTBLFile.eof() && (TrainTimetableString[0] ==
'\0'))
16792 AnsiString OneLine(TrainTimetableString);
16793 bool FinalCallTrue =
true;
16795 CheckLocationsExistInRailway))
16797 TTBLFile.getline(TrainTimetableString, 10000,
'\0');
16798 if(TTBLFile.eof() && (TrainTimetableString[0] ==
'\0'))
16801 throw Exception(
"Timetable FinalCall error - no start time on own line, Count = 0");
16803 OneLine = AnsiString(TrainTimetableString);
16809 TTBLFile.getline(TrainTimetableString, 10000,
'\0');
16810 if(TTBLFile.eof() && (TrainTimetableString[0] ==
'\0'))
16816 OneLine = AnsiString(TrainTimetableString);
16821 throw Exception(
"Timetable FinalCall error in processing one timetable line, Count = " + AnsiString(Count));
16823 if(EndOfFile && (Count < 2))
16826 throw Exception(
"Timetable FinalCall error - too few or no relevant entries, Count = " + AnsiString(Count));
16831 delete TrainTimetableString;
16863 std::ifstream InFile(FileName.c_str());
16865 int NumberOfActiveElements;
16866 bool GraphicsFollow =
false;
16868 if(InFile.is_open())
17015 if((TempString !=
"***BarriersDownVector***") && (TempString !=
"***Timetable***"))
17021 if(TempString ==
"***BarriersDownVector***")
17059 ShowMessage(
"Session file failed to open, unable to load session. Ensure that there is a folder named " +
SESSION_DIR_NAME +
17060 " in the folder where the 'Railway.exe' program file resides");
17067 InFile.open(FileName.c_str());
17068 if(InFile.is_open())
17089 bool GraphicsFollow =
false;
17210 if((TempString !=
"***BarriersDownVector***") && (TempString !=
"***Timetable***"))
17216 if(TempString ==
"***BarriersDownVector***")
17295 InFile.get(TempChar);
17296 while(!InFile.eof() && ((TempChar ==
'\n') || (TempChar ==
'\0')))
17298 InFile.get(TempChar);
17329 double PowerDouble;
17359 AnsiString TempString =
"", Line1 =
"", Line2 =
"", Line3 =
"", Line4 =
"", Line5 =
"";
17360 char *Buffer =
new char[1000];
17363 InFile.get(TempChar);
17364 InFile.getline(Buffer, 1000);
17365 TempString = AnsiString(Buffer);
17366 while(TempString !=
"***End of performance file***")
17370 InFile.getline(Buffer, 1000);
17371 TempString = AnsiString(Buffer);
17382 AnsiString TempString =
"";
17385 InFile.get(TempChar);
17386 if(TempChar !=
'\n')
17396 while(TempString !=
"***End of performance file***")
17417 AnsiString OneLine = Text.SubString(1, Text.Pos(
'\x0D'));
17418 while((OneLine.Length() > 0) && OneLine[OneLine.Length()] <
' ')
17419 OneLine.SetLength(OneLine.Length() - 1);
17420 Text = Text.SubString(Text.Pos(
'\x0D'), Text.Length());
17421 while((Text.Length() > 0) && Text[1] <
' ')
17422 Text = Text.SubString(2, (Text.Length() - 1));
17423 OutFile << OneLine.c_str() <<
'\n';
17442 InfoPanel->Caption =
"PRE-START: Select AUTOMATIC SIGNAL ROUTE start signal, or left click points to change manually";
17444 InfoPanel->Caption =
"OPERATING: Select AUTOMATIC SIGNAL ROUTE start signal, or left click points to change manually";
17454 InfoPanel->Caption =
"PRE-START: Select PREFERRED ROUTE start signal, or left click points to change manually";
17456 InfoPanel->Caption =
"OPERATING: Select PREFERRED ROUTE start signal, or left click points to change manually";
17466 InfoPanel->Caption =
"PRE-START: Select UNRESTRICTED ROUTE start location, or left click points to change manually";
17468 InfoPanel->Caption =
"OPERATING: Select UNRESTRICTED ROUTE start location, or left click points to change manually";
17479 InfoPanel->Caption =
"PRE-START: Select UNRESTRICTED ROUTE start location, or left click points to change manually";
17481 InfoPanel->Caption =
"OPERATING: Select UNRESTRICTED ROUTE start location, or left click points to change manually";
17507 InfoPanel->Caption =
"Left click screen to zoom in at that position";
17512 InfoPanel->Caption =
"PAUSED: Railway state changes disabled";
17585 Screen->Cursor = TCursor(-11);
17586 AnsiString ErrorFileStr =
CurDir +
"\\errorlog.err";
17587 std::ofstream ErrorFile(ErrorFileStr.c_str());
17589 if(!(ErrorFile.fail()))
17592 int ScreenX = Mouse->CursorPos.x -
MainScreen->ClientOrigin.x;
17593 int ScreenY = Mouse->CursorPos.y -
MainScreen->ClientOrigin.y;
17594 AnsiString MouseStr =
"Posx: " + AnsiString(ScreenX) +
"; Posy: " + AnsiString(ScreenY);
17604 ErrorFile << Item.c_str() <<
'\n';
17611 ErrorFile << Item.c_str() <<
'\n';
17720 Screen->Cursor = TCursor(-2);
17737 int TempTTFileNumber = 0;
17739 while(FileExists(
CurDir +
"\\TmpTT" + AnsiString(TempTTFileNumber) +
".tmp"))
17741 TempTTFileNumber++;
17744 int InHandle = FileOpen(InFileName, fmOpenRead);
17747 while(InHandle < 0)
17749 InHandle = FileOpen(InFileName, fmOpenRead);
17754 ShowMessage(
"Failed to open timetable file, make sure it's not open in another application");
17762 while(OutHandle < 0)
17769 ShowMessage(
"Failed to save temporary timetable file, sessions can't be saved - try again, may only be a temporary problem");
17770 FileClose(InHandle);
17775 int CountIn, CountOut;
17776 char *Buffer =
new char[10000];
17780 CountIn = FileRead(InHandle, Buffer, 10000);
17781 CountOut = FileWrite(OutHandle, Buffer, CountIn);
17782 if(CountOut != CountIn)
17784 ShowMessage(
"Error in writing to the temporary timetable file, sessions can't be saved - try again, may only be a temporary problem");
17786 FileClose(InHandle);
17787 FileClose(OutHandle);
17791 if(CountIn < 10000)
17795 FileClose(InHandle);
17796 FileClose(OutHandle);
17841 int VarElements = 0;
17842 bool NamedLocPresent =
false;
17850 throw Exception(
"Error - failed to find track element at " + AnsiString(TE.
HLoc) +
" & " + AnsiString(TE.
VLoc) +
" in SetLengths");
17857 NamedLocPresent =
true;
17863 if(SpeedLimit != -1)
17868 if(SpeedLimit != -1)
17878 if((NamedLocPresent) && (VarElements > 0) && ((Distance / VarElements) < 50))
17880 ShowMessage(
"Note: Named location elements are quite short. If they are too short the simulation might depart too far from reality.");
17883 if((NamedLocPresent) && (VarElements > 0) && ((Distance / VarElements) > 200))
17885 ShowMessage(
"Note: Named location elements are quite long. If they are too long the simulation might depart too far from reality.");
17894 if((VarElements * 20) > Distance)
17896 ShowMessage(
"Required distance is less than the minimum, will set each element to the minimum (20m)");
17897 Distance = (VarElements * 20);
17899 if(VarElements == 0)
17902 ShowMessage(
"No elements selected");
17908 int RemainingDistance = Distance, RemainingVarElements = VarElements, NextLength = RemainingDistance / VarElements;
17916 if(NextLength < 20)
17940 RemainingDistance -= NextLength;
17941 RemainingVarElements--;
17942 if(RemainingVarElements > 0)
17943 NextLength = RemainingDistance / RemainingVarElements;
17968 ShowMessage(
"Nothing to save!");
17973 SaveRailwayDialog->Filter =
"Development file (*.dev)|*.dev|Railway file (*.rly)|*.rly";
17979 Screen->Cursor = TCursor(-11);
17981 AnsiString Extension =
"";
17989 if(!(VecFile.fail()))
18017 if((LastChar ==
'y') || (LastChar ==
'Y'))
18045 ShowMessage(
"File open failed prior to save");
18049 ShowMessage(
"Can't save: extension must be either '.dev', or '.rly' with railway ready for operation");
18051 Screen->Cursor = TCursor(-2);
18149 bool TextFound =
false;
18172 AnsiString(VPos) +
"," + AnsiString((
short)UseEnteredPosition));
18173 int VPosHi, VPosLo, TextPosHi, TextPosLo;
18176 if(!UseEnteredPosition)
18183 int Depth = abs(Font->Height);
18184 TextPosHi = VPosHi + 20;
18185 TextPosLo = VPosLo - Depth - 4;
18188 if(TextPosLo >= ScreenPosLo)
18190 else if(TextPosHi < ScreenPosHi)
18193 VPos = ScreenPosLo + 288;
18239 catch(
const Exception &e)
18316 AnsiString OpTimeToActDisplay;
18317 AnsiString OpTimeToActString;
18318 AnsiString HeadCode;
18319 float OpTimeToActFloat;
18331 HeadCode = HCandTrainPosParam.first;
18332 if(OpTimeToActFloat < 0.25)
18334 OpTimeToActString =
"NOW";
18336 else if(OpTimeToActFloat < 1)
18338 OpTimeToActString =
"<1";
18342 OpTimeToActString = AnsiString(floor(OpTimeToActFloat));
18344 if(OpTimeToActFloat < 60)
18346 OpTimeToActDisplay = HeadCode + AnsiString(
'\t') + OpTimeToActString;
18347 OAListBox->Items->Add(OpTimeToActDisplay);
18372 TPicture *PicPtr =
new TPicture;
18374 UGME.second = PicPtr;
18385 catch(
const EInvalidGraphic &e)
18388 "Incorrect file format, the file can't be loaded.\nEnsure that the file you want is a valid graphic file with extension .bmp, .gif, .jpg, or .png");
18390 catch(
const Exception &e)